Skip Menu |
Report information
Id: 129798
Status: new
Priority: 0/
Queue: perl6

Owner: Nobody
Requestors: nando.santagata [at] gmail.com
Cc:
AdminCc:

Severity: (no value)
Tag: (no value)
Platform: (no value)
Patch Status: (no value)
VM: (no value)



Subject: Fwd: Initializing a CStruct attribute of a CStruct
To: rakudobug [...] perl.org
From: Fernando Santagata <nando.santagata [...] gmail.com>
Date: Mon, 3 Oct 2016 15:54:59 +0200
Download (untitled) / with headers
text/plain 2.7k
As requested:

---------- Forwarded message ----------
From: Elizabeth Mattijsen <liz@dijkmat.nl>
Date: Mon, Oct 3, 2016 at 3:26 PM
Subject: Re: Initializing a CStruct attribute of a CStruct
To: perl6-users <perl6-users@perl.org>


recently, jnthn fixed a bug in attribute binding of natives in signatures, so you should now be able to say:

  submethod BUILD(uint64 :$!c, test1 :$!d) { }  # should work, but doesn't

which in turn begs the question why you would need the BUILD anyway.  But indeed it looks like you need to do the binding yourself.

  submethod BUILD(uint64 :$!c, test1 :$d) { $!d := $d }  # works, but shouldn’t be necessary


Please rakudobug this (by sending an email to rakudobug@perl.org).


Thanks!


Liz

> On 03 Oct 2016, at 14:50, Fernando Santagata <nando.santagata@gmail.com> wrote:
>
> 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.santagata@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




--
Fernando Santagata


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

For issues related to this RT instance (aka "perlbug"), please contact perlbug-admin at perl.org