Moops lexical_has和默认值

G. *_*ito 8 oop perl moose moops

我试图了解lexical_has属性如何在Moops中运行.这个特性来自,Lexical::Accessor并且据我所知,该lexical_has函数能够通过使用标量引用(保留在其中)生成CODEclass可能"词法上具有"的任何属性的引用accessor =>.然后可以使用CODE引用以"强制"范围的方式访问类属性(因为它们是"由内而外"??).但这只是我的猜测和猜测,所以我希望得到一个更好的解释.我也想知道为什么这种方法在以下示例中似乎不起作用:

Moops介绍中的一个例子开始,我正在创建一个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;  
    }    
}     
Run Code Online (Sandbox Code Playgroud)

然后我实例化该对象并尝试使用其方法来访问其属性:

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();
Run Code Online (Sandbox Code Playgroud)

使用自定义访问器的最后一行让我感到困惑:没有任何反应.我是否缺少类的属性或设置(标记为急切或lazy => 0无效)?我需要一个BUILD功能吗?我缺少一个初始化步骤吗?

注意如果我在类中添加一个setter方法,如下所示:

method set_top_speed (Int $num) {   
    $self->$max_speed($num);
}
Run Code Online (Sandbox Code Playgroud)

然后在我的最后一系列陈述中调用它:

# shows expected error "too fast"
$solarcharged->speed(140);

$solarcharged->set_top_speed(100);

# prints 100
say $solarcharged->get_top_speed();
Run Code Online (Sandbox Code Playgroud)

get_top_speed()方法开始正常返回.这是预期的吗?如果是这样,类设置的默认值如何工作?


我在这里报告了这个错误:https://rt.cpan.org/Public/Bug/Display.html?id = 101024.

由于One可以通过使用"perl约定"(不使用lexical_has和使用" _" 来使用私有属性前缀)来轻松解决这个问题,并且这个问题来自一个错误,我不希望修复或补丁作为答案.对于奖金-我会很感激的是如何解释Lexical::Accessor认为工作; 它如何"强制"访问者的私人内部范围; 也许是一些关于为什么这是好事的CS理论.