Looks like the solution is declaring the parameter type in the BUILD
submethod. This one works fine:

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;
  submethod BUILD(uint64 :$c, test1 :$d){
    $!c = $c;
    $!d := $d;
  }
}

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

On Sat, Oct 1, 2016 at 10:34 AM, Fernando Santagata <
nando.santag...@gmail.com> wrote:

> 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
>



-- 
Fernando Santagata

Reply via email to