Here's my very naive way of doing it.
class A does Positional {
has $.a0 is rw;
has $.a1 is rw;
has $.a2 is rw;
has $.a3 is rw;
has $.a4 is rw;
has $.a5 is rw;
has @!arr;
method TWEAK {
@!arr[0] := $.a0;
@!arr[1] := $.a1;
@!arr[2] := $.a2;
@!arr[3] := $.a3;
@!arr[4] := $.a4;
@!arr[5] := $.a5;
}
multi method elems() { 6 }
multi method AT-POS( $index ) {
return @!arr[$index];
}
multi method ASSIGN-POS( $index, $new ) {
@!arr[$index] = $new;
}
}
On Sat, 28 Oct 2017 at 09:45 Fernando Santagata <[email protected]>
wrote:
> Hello,
>
> I was trying to write a NativeCall interface to a C library, but I
> stumbled upon a problem (
> https://stackoverflow.com/questions/44266457/array-of-structs-as-an-attribute-of-a-perl-6-nativecall-struct
> ).
> The best way to solve that problem would be to add a new keyword to the
> NativeCall module, which I think is quite hard, so I'm trying a less fancy
> alternative.
>
> The problem itself looks like this: I have a class with a bunch of
> elements which I would like to access as an array (I can't use a Perl6
> Array in a NativeCall class).
>
> Reducing the problem to the bare bones, my class looks like
>
> Class A {
> has $.a0 is rw;
> has $.a1 is rw;
> has $.a2 is rw;
> has $.a3 is rw;
> has $.a4 is rw;
> }
>
> My first attempt was to use meta methods to access the attributes:
>
> class A does Positional {
> has $.a0 is rw;
> has $.a1 is rw;
> has $.a2 is rw;
> has $.a3 is rw;
> has $.a4 is rw;
> method AT-POS($index) is rw {
> my $a = A.^attributes(:local)[$index];
> $a.get_value(self);
> }
> }
>
> This works if I just need to read the values, but if I needed to write
> them I should use the set_value metamethod:
>
> $a.set_value(self, $value);
>
> The detail I miss is: how do I know whether the AT-POS method has been
> called to produce an rvalue or an lvalue?
>
> The second attempt was to use a Proxy object:
>
> class A does Positional {
> has $.a0 is rw;
> has $.a1 is rw;
> has $.a2 is rw;
> has $.a3 is rw;
> has $.a4 is rw;
> method AT-POS(::?CLASS:D: $index) is rw {
> my $a = A.^attributes(:local)[$index];
> Proxy.new(
> FETCH => method () { $a.get_value(self) },
> STORE => method ($value) { $a.set_value(self, $value) }
> );
> }
> }
>
> sub MAIN
> {
> my A $a .= new;
> $a.a0 = 0;
> $a.a1 = 1;
> say $a[0];
> say $a[1];
> say $a[2];
> $a[0] = 42;
> say $a[0];
> }
>
> But this program just hangs.
> When run in the debugger I get this:
>
> >>> LOADING Proxy.p6
> + Exception Thrown
> | Died
> + Proxy.p6 (25 - 29)
> | }
> |
> | sub MAIN
> | {
> | my A $a .= new;
>
> I'm clueless here.
> What am I doing wrong?
> Can anyone help?
>
> Thank you!
>
> --
> Fernando Santagata
>