简单地说:
当从字面量创建时,它可能不那么明显,但当与另一个对象一起使用时,我认为很明显:
role R { method answer { 42 } }
my $question = 'question';
my $but = $question but R;
my $does = $question does R;
say $question.WHAT;
say $but.WHAT;
say $does.WHAT; Â
say $question.WHERE;
say $but.WHERE;
say $does.WHERE;
注意,我作弊了一点,换了顺序
做
和
但是
.如果我保留了你的订单
做
将修改
$question
到位,应用角色,这意味着
但是
会克隆
$问题
(及其角色)并应用该角色(再次!):
my $does = $question does R;
my $but = $question but R;
say $does.WHAT;
say $but.WHAT;
这是因为
做
因为运算符在概念上类似于
++
或
+=
也就是说,设计用于独立环境,例如
my $foo = â¦;
given $bar {
when 'a'Â {Â $foo does A }
when 'b'Â {Â $foo does B }
when 'c'Â {Â $foo does B }
}
使用
但是
在概念上更接近于使用
$foo + 1
除非分配给或传递给其他东西,否则大多毫无意义。
警告
做
和值类型
如果你使用
做
在a
值类型
(主要是字符串和数字),你极有可能造成意想不到的副作用。这是因为值类型(例如字符串)应该是不可变的,并且可以相互替换。注意以下事项:
role Fooish { }
my $foo = 'foo';
$foo does Fooish;
say 'foo'.WHAT;
这是在编译时发生的替换(因此它不会影响,例如,
'foobar'.substr(0,3)
,这发生在运行时),但如果你把它们扔进循环中,可能会导致一些真正奇怪的效果:
role Fooish { }
my @a;
@a.push('foo' does Fooish) for ^10;
say @a[0].WHAT;
+{Fooish}+{Fooish}+{Fooish}+{Fooish}+{Fooish})
你做得越多,应用多个卷的时间就越长,所以如果你将其更改为^100000,请准备好等待一段时间。OTOH,做
但是
给你很好的恒定时间,不会污染字面意思。AFAICT,这种行为似乎是完全有效的,但肯定会让你措手不及。