Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl6 Using Proxy to trigger on attribute access

Tags:

raku

I am trying to implement a trigger on write access to a perl6 Class attribute. I cannot figure out the cause of the error...

... I got this notion from How does one write custom accessor methods in Perl6?

  1 #!/usr/bin/env perl6
  2 
  3 class MeasureSP {
  4 
  5     has Real $!value;
  6     has Str  $.units;
  7 
  8     submethod BUILD( :$!value, :$!units ) {}
  9 
 10     method value( Real $newval? ) is rw {
 11         return Proxy.new:
 12             FETCH => sub ($)           { $!value },
 13             STORE => sub ($, $newval)  { $!value = $newval },             
 14     }   
 15     
 16 }   
 17 my MeasureSP $m-sp = MeasureSP.new( value => 23, units => 'metres' );
 18 say $m-sp.units;   #metres
 19 say $m-sp.value;   #23
 20 $m-sp.value = 1;   
 21 # Cannot assign to a readonly variable or a value
 22 #in block <unit> at ./retry.p6 line 20

This behaviour seems to have changed - this code was working fine back in June 18 - but I want to be sure I am in step with the latest thinking.

Any help would be very much appreciated !

like image 646
p6steve Avatar asked Dec 31 '18 17:12

p6steve


1 Answers

Either remove the return:

method value( Real $newval? ) is rw {
    Proxy.new:
        FETCH => sub ($)           { $!value },
        STORE => sub ($, $newval)  { $!value = $newval },
}

Or use return-rw if you really want to be explicit:

method value( Real $newval? ) is rw {
    return-rw Proxy.new:
        FETCH => sub ($)           { $!value },
        STORE => sub ($, $newval)  { $!value = $newval },
}

The problem is that return will strip away any item container, so just putting is rw on the method is not enough on its own.

As to why the posted code used to work, but no longer does: Rakudo releases in the last couple of months have included a fix for a bug that meant Proxy was treated differently than Scalar in routine return handling. The Proxy was not stripped in places it should have been; now it reliably is.

like image 53
Jonathan Worthington Avatar answered Dec 17 '22 11:12

Jonathan Worthington