> On 17 Nov 2017, at 20:09, Fernando Santagata <[email protected]>
> 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