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 <nando.santag...@gmail.com> 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 >