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 <
[email protected]> wrote:
> Hi Liz,
>
> Thank you and my regards to Moritz too!
>
> On Fri, Nov 17, 2017 at 11:14 PM, Elizabeth Mattijsen <[email protected]>
> wrote:
>
>> > On 17 Nov 2017, at 22:47, Elizabeth Mattijsen <[email protected]> wrote:
>> >> 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($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