11

我试图了解lexical_has属性如何在Moops中工作。此功能来自,Lexical::Accessor并且据我了解,该lexical_has函数能够通过使用标量引用(保存在 中)生成对可能“在词法上具有”的CODE任何属性的引用。然后可以使用 CODE 引用以“强制”范围的方式访问类属性(因为它们是“由内而外”的??)。但这只是我的猜测和疯狂的猜测,所以我希望能有更好的解释。我还想知道为什么这种方法在以下示例中似乎不起作用:classaccessor =>

从作为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;  
    }    
}     

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

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函数吗?我缺少初始化步骤吗?

注意如果我向类中添加一个 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 。

由于人们可以通过使用“perl 约定”(即不使用lexical_has私有属性并在私有属性前加上“ ”)轻松解决_这个问题,而且这个问题是由错误引起的,因此我不希望修复或修补程序作为答案。对于赏金-我希望能解释一下Lexical::Accessor应该如何工作;它如何“强制”访问者的私有内部范围;也许还有一些关于为什么这是一件好事的 CS 理论。

4

1 回答 1

1

根据 OP 提交的票证,此错误已在 Lexical-Accessor 0.009 中修复。

于 2020-07-26T11:10:27.523 回答