Perl6使用代理触发属性访问

时间:2018-12-31 17:52:07

标签: perl6

我试图在对perl6 Class属性的写访问上实现一个触发器。我无法找出错误原因...

...我从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

这种行为似乎已经改变-这段代码在6月18日运行良好-但我想确保我能顺应最新的想法。

任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:13)

删除return

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

或者如果您确实想露骨,请使用return-rw

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

问题在于return会剥离所有项目容器,因此仅将is rw放在method上是不够的。

关于为何发布的代码曾经起作用但不再起作用的原因:Rakudo在过去几个月中发布的版本中包含了一个错误的修复程序,该错误意味着Proxy在{例行退货处理。 Scalar并未在应有的位置剥离;现在确实是。