Category: Perl6 Keywords: delegation handles Perl6
Delegation
Delegation, 中文的意思可以为代表,授权或是委托。Delegation 能让你在一个 class 或 role 里把另一个对象的方法当成自己的。
例子用于理解
class Dog {
method wag { 2 }
method run { 100 }
}
class Wolf {
method wag { 4 }
}
class Snoopy {
has $.tail handles 'wag';
}
my $pet = Snoopy.new;
# $pet.wag; 错误,不知道 $.tail 对应哪个类
$pet.tail = Dog.new; # 这里的 $pet 没有继承 Dog 类
$pet.wag; # 2
$pet.tail = Wolf.new; # 将 $.tail 对应到 Wolf
$pet.wag; # 4, $.tail 对应 Wolf, 所以调用 Wolf.wag;
其中最关键的一句就是 has $.tail handles 'wag'; 它使类 Snoopy 产生了一个方法 wag. 而调用 wag 就等同于调用 $.tail.wag 所以这话也就等同于在类里定义了如下代码:
method wag (*@args is context(Lazy)) { $.tail.wag(*@args) }
关键字 handles 的中文意思可以为处理。所以代码 has $.tail handles 'wag' 的字面意思理解可以为“用 $.tail 来处理 wag 调用”。
方法多样化
- 如果要多于一个方法的话,可以这么表示:
has $.tail handles <wag run>; - 其实我们是用智能匹配来处理 handles 后面的参数。比如:
has $:fur handles /^get_/; # 智能匹配正则表达式,所以以 get_ 开头的方法调用都委托 $:fur 对象来处理 has $:fur handles Groomable; # handles 的方法就是 Groomable 里的所有方法
- 如果你想定义一个方法名字而实际调用的是另一个方法,可以使用 Pair.
has $:fur handles { :shakefur<shake> :scratch<get_fleas> }; # 当你调用 shakefur 时实际上调用了 $:fur.shake - 可以更进一步,使用正则替换来改变方法名:
has $:fur handles (s/^furget_/get_/); # 当你调用 furget_a 时实际调用的是 get_a