如何在Perl6中编写自定义访问器方法?

如果我有这堂课:



class Wizard {
    has Int $.mana is rw;
}


我可以做这个:



my Wizard $gandalf .= new;
$gandalf.mana = 150;


假设我想在不放弃$gandalf.mana = 150;表示法的情况下向我的Perl6类中的setter添加一点检查(换句话说,我不想这样写:$gandalf.setMana(150);)。如果程序尝试设置负法力,则该程序应终止。我该怎么做呢? Perl6文档仅提到可以编写自定义访问器,但是没有说明如何编写。

最佳答案

您可以通过声明方法$.mana获得与说is rw提供的访问器接口相同的接口。然后,您可以将代理包装在基础属性周围,如下所示:

#!/usr/bin/env perl6
use v6;

use Test;
plan 2;

class Wizard {
    has Int $!mana;

    method mana() is rw {
        return Proxy.new:
            FETCH => sub ($) { return $!mana },
            STORE => sub ($, $mana) {
                die "It's over 9000!" if ($mana // 0) > 9000;
                $!mana = $mana;
            }
    }
}

my Wizard $gandalf .= new;
$gandalf.mana = 150;
ok $gandalf.mana == 150, 'Updating mana works';
throws_like sub {
    $gandalf.mana = 9001;
}, X::AdHoc, 'Too much mana is too much';


Proxy基本上是一种拦截对存储的读写调用并执行默认行为以外的操作的方法。正如它们的大小写所暗示的那样,Perl会自动调用FETCHSTORE来解析诸如$gandalf.mana = $gandalf.mana + 5之类的表达式。

PerlMonks上有更全面的讨论,包括您是否应该尝试这样做。我建议不要使用上述属性-和一般的rw公共属性。与有用的工具相比,它更多地显示了用语言表达的内容。

关于raku - 如何在Perl6中编写自定义访问器方法?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31665384/

10-12 14:20