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
>

Reply via email to