> 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)) } ) }); } class A { has $!a is proxy({ $^a * 2 }); has $!b is proxy({ $^a * 3 }); } my A $a .= new; $a.a = 21; say $a.a; # 42 $a.b = 21; say $a.b; # 63 ===================================== Unfortunately, this involves some MONKEY guts… lemme see if I can figure out a way for you not to have to do that. Liz