是否可以覆盖角色的属性以提供默认值?
role A {
has $.a;
}
class B does A {
has $.a = "default";
}
my $b = B.new;
这会导致编译错误:
===SORRY!=== Error while compiling:
Attribute '$!a' already exists in the class 'B', but a role also wishes to compose it
答案 0 :(得分:5)
由于R
中的方法可能会引用$!a
,因此会引起含糊不清的属性。
使用子方法BUILD初始化inherited / mixedin属性。
role R { has $.a };
class C does R {
submethod BUILD { $!a = "default" }
};
my $c = C.new;
dd $c;
# OUTPUT«C $c = C.new(a => "default")»
根据您的用例,您最好通过角色参数设置默认值。
role R[$d] { has $.a = $d };
class C does R["default"] { };
my $c = C.new;
dd $c;
# OUTPUT«C $c = C.new(a => "default")»
答案 1 :(得分:1)
不,重新声明属性是不可能的 - 但您可以使用类的BUILD
子方法对其进行初始化:
role A {
has $.a;
}
class B does A {
submethod BUILD(:$!a = 'default') {}
}
请注意,如果您只是在BUILD
正文中设置值而不是通过
class B does A {
submethod BUILD { $!a = 'default' }
}
用户无法通过B.new(a => 42)
提供命名的初始值设定项来覆盖默认值。
另一个更优雅的方法,如果设置默认值是你期望做的很多事情(即默认值可以被视为角色界面的一部分)特别有用的方法是使它成为一个参数:
role A[$d] {
has $.a = $d;
}
class B does A['default'] {}