Hello,

I'm trying to do something complex (at least for me :-) with NativeCall.

Let's start with plain Perl6. This:

class test1 {
  has Int  $.a;
  has Int  $.b;
}

class test2 {
  has Int   $.c;
  has test1 $.d;
}

my test2 $t2 .= new(:3c, d => test1.new(:1a :2b));
dd $t2;

outputs:

test2 $t2 = test2.new(c => 3, d => test1.new(a => 1, b => 2))


But I need to do that with CStructs. This code:

use NativeCall;

class test1 is repr('CStruct') is export {
  has uint64  $.a;
  has uint64  $.b;
}

class test2 is repr('CStruct') is export {
  has uint64  $.c;
  has test1   $.d;
}

my test2 $t2 .= new(:3c, d => test1.new(:1a :2b));
dd $t2;

doesn't really work and outputs this:

Cannot modify an immutable test1


Adding a BUILD submethod isn't enough:

submethod BUILD(:$!c, :$!d) { }

What I get is:

CStruct can't perform boxed get on flattened attributes yet


and this:

submethod BUILD(:$c, :$d){
  $!c = $c;
  $!d := $d;
}

doesn't work either:

Can only store CStruct attribute in CStruct slot in CStruct


But this one does:

submethod BUILD(:$c, :$d){
  $!c = $c;
  $!d := test1.new(a => $d.a, b => $d.b);
}

Only, I don't want to initialize all the attributes one by one...
Is there a less cumbersome way to do that initialization?

Thanks!

-- 
Fernando Santagata

Reply via email to