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($val >> ue)) >> > } >> > ) >> > }); >> > } >> >> 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