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

Reply via email to