我试图了解lexical_has
属性在Moops中的工作原理。此功能来自Lexical::Accessor
,据我了解,lexical_has
函数可以生成CODE
对class
可能“词法上具有”的任何属性的引用标量引用(保存在accessor =>
中)。然后可以使用CODE引用以“强制”范围的方式访问类属性(因为它们是“由内而外”??)。但这只是我的猜测和猜测,所以我希望得到一个更好的解释。我也想知道为什么这种方法在以下示例中似乎不起作用:
使用属于Moops introduction我正在创建class Car
的一部分的示例:
use Moops;
class Car {
lexical_has max_speed => (
is => 'rw',
isa => Int,
default => 90,
accessor => \(my $max_speed),
lazy => 1,
);
has fuel => (
is => 'rw',
isa => Int,
);
has speed => (
is => 'rw',
isa => Int,
trigger => method ($new, $old?) {
confess "Cannot travel at a speed of $new; too fast"
if $new > $self->$max_speed;
},
);
method get_top_speed() {
return $self->$max_speed;
}
}
然后我实例化对象并尝试使用其方法来访问其属性:
my $solarcharged = Car->new ;
# This correctly won't compile due to $max_speed scoping:
# say $solarcharged->$max_speed;
# This shows expected error "too fast"
$solarcharged->speed(140);
# This prints nothing - wrong behavior?
say $solarcharged->get_top_speed();
使用自定义访问器的最后一行让我困惑:没有任何反应。我是否缺少类的属性或设置(标记为急切或lazy => 0
不起作用)?我需要BUILD
功能吗?我缺少一个初始化步骤吗?
N.B。如果我在类中添加一个setter方法,如下所示:
method set_top_speed (Int $num) {
$self->$max_speed($num);
}
然后在我的最后一系列陈述中调用它:
# shows expected error "too fast"
$solarcharged->speed(140);
$solarcharged->set_top_speed(100);
# prints 100
say $solarcharged->get_top_speed();
get_top_speed()
方法开始正常返回。这是预期的吗?如果是这样,类设置的默认值如何工作?
我在此处将此报告为错误:https://rt.cpan.org/Public/Bug/Display.html?id=101024。
由于One可以通过使用“perl约定”(即不使用lexical_has
并使用“_
”为私有属性添加前缀来轻松解决此问题,因此这个问题来自于一个错误,我不希望修复或补丁作为答案。对于赏金 - 我希望解释Lexical::Accessor
假设如何工作;它如何“强制”访问者的私人内部范围;也许是一些关于为什么这是好事的CS理论。