Ah, duh, yes, should be a multi  :-)

> On 18 Nov 2017, at 19:33, Fernando Santagata <nando.santag...@gmail.com> 
> wrote:
> 
> The last iteration of this code snippet is:
> 
> multi sub trait_mod:<is>(Attribute:D \attribute, :&proxy!) {
>   attribute.package.^add_method(attribute.name.substr(2), my method ($SELF:) {
>     Proxy.new(
>       FETCH => { attribute.get_value($SELF) },
>       STORE => -> $, \value { attribute.set_value($SELF,proxy(value)) }
>     )
>   });
> }
> 
> class A {
>   has $.test is rw;
>   has $!a is proxy({ $^a * 2 });
>   has $!b is proxy({ $^a * 3 });
> }
> 
> my A $a .= new;
> $a.a = 21;
> say $a.a;
> $a.b = 21;
> say $a.b;
> 
> The "multi" is necessary, otherwise the declared "is proxy" trait becomes the 
> only one possible and the "is rw" trait of the $.test attribute generates a 
> compile-time error.
> 
> On Sat, Nov 18, 2017 at 6:24 PM, Fernando Santagata 
> <nando.santag...@gmail.com> wrote:
> Hi Liz,
> 
> Thank you and my regards to Moritz too!
> 
> On Fri, Nov 17, 2017 at 11:14 PM, Elizabeth Mattijsen <l...@dijkmat.nl> wrote:
> > On 17 Nov 2017, at 22:47, Elizabeth Mattijsen <l...@dijkmat.nl> wrote:
> >> On 17 Nov 2017, at 20:09, Fernando Santagata <nando.santag...@gmail.com> 
> >> wrote:
> >> I tried to use the code you suggested:
> >>
> >> sub trait_mod:<is>(Attribute:D \attribute, :&proxy!) {
> >>  attribute.package.^add_method(attribute.name, my method () { proxy($_) })
> >> }
> >>
> >> class A {
> >>  has $!a is proxy({ $^a * 2 });
> >>  has $!b is proxy({ $^a * 3 });
> >> }
> >>
> >> my A $a .= new;
> >> $a.a = 21;    # <-- No such method 'a' for invocant of type 'A'
> >> say $a.a;
> >> $a.b = 21;
> >> say $a.b;
> >>
> >> But I got an error on the first assignment.
> >> What am I doing wrong?
> >
> > Ok, finally had some time to figure this out more deeply.  My result:
> > =====================================
> > sub trait_mod:<is>(Attribute:D \attribute, :&proxy!) {
> >    my $name   = attribute.name;
> >    my $method = $name.substr(2);
> >    attribute.package.^add_method($method, my method ($SELF:) is raw {
> >        use MONKEY-GUTS;
> >        Proxy.new(
> >          FETCH => { nqp::getattr(nqp::decont($SELF),$SELF.WHAT,$name) },
> >          STORE => -> $, $value {
> >            nqp::bindattr(nqp::decont($SELF),$SELF.WHAT,$name,proxy($value))
> >          }
> >        )
> >    });
> > }
> 
> And this would be the version without MONKEY-GUTS, moritz++
> 
> ====================================
> sub trait_mod:<is>(Attribute:D \attribute, :&proxy!) {
>     attribute.package.^add_method(attribute.name.substr(2), my method 
> ($SELF:) {
>         Proxy.new(
>           FETCH => { attribute.get_value($SELF) },
>           STORE => -> $, \value { attribute.set_value($SELF,proxy(value)) }
>         )
>     });
> }
> ====================================
> 
> Turns out the Attribute class has a set_value and get_value method.  Which 
> moritz++ pointed out to me on #perl6-dev.  So no need to get gutsy!
> 
> 
> 
> Liz
> 
> 
> 
> -- 
> Fernando Santagata
> 
> 
> 
> -- 
> Fernando Santagata

Reply via email to