我有一个类可以扮演另一个角色.该类中的方法可以访问顶级角色中的属性:
role A {
has $.x
}
role B does A {
}
class C does B {
method this() { say $!x }
}
C.new(:x(1)).this;
Run Code Online (Sandbox Code Playgroud)
这工作正常,并说我认为应该如此.
但我有很多类都做角色B,我想分享方法this(),所以我把它移到角色B:
role A {
has $.x
}
role B does A {
method this() { $!x }
}
class C does B {}
C.new(:x(1)).this;
Run Code Online (Sandbox Code Playgroud)
那甚至都不会编译:SORRY Attribute $!x not declared in role B.
角色是否可以在其包含的角色中看不到属性?
这样做需要在第一个角色中引入私有方法,并通过以下方式访问:
role A {
has $.x;
method !x() { $!x }
}
role B does A {
method this() { self!x }
}
class C does B {}
say C.new(:x(1)).this; # 1
Run Code Online (Sandbox Code Playgroud)
原始代码不起作用的原因 - 并且使其工作并不容易 - 是角色是通用的并且可能使用不同的类型参数集重载,因此提及角色本身是通用的.因此,一般而言,does A不识别具体的目标角色; 可能有多个,他们可能有不同的属性.直到我们将角色组成一个类,我们才最终确定组成的具体角色集.
但是,属性访问是一种变量访问,因此在我们编译角色时进行检查.在最后一堂课中,这不是一个问题,因为我们在那时选择了我们将要使用的所有具体角色; 这就是为什么它可以轻松地在那里工作.对于这种role情况,我们无法真正检查它们,直到组成一个最终类,这可能是一个单独的编译单元.这可能是一个可解决的问题,未来的Perl 6语言版本可以为此指定一种方法.目前,它保守地没有.