Moops lexical_has и значения по умолчанию

Я пытаюсь понять как lexical_has Атрибуты работают в Moops. Эта функция исходит от Lexical::Accessor и, насколько я понимаю, lexical_has функция может генерировать CODE ссылка на любой атрибут class может "лексически иметь" с помощью скалярной ссылки (которая хранится в 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;  
    }    
}     

Затем я создаю экземпляр объекта и пытаюсь использовать его методы для доступа к его атрибутам:

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 функционировать? Я пропускаю шаг инициализации?

NB. Если я добавлю метод установки в класс, который выглядит следующим образом:

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 должен работать; как это "обеспечивает" частную внутреннюю область доступа; и, может быть, какая-то теория о том, почему это хорошо.

0 ответов

Согласно заявке, поданной OP, эта ошибка была исправлена ​​в Lexical-Accessor 0.009.

Другие вопросы по тегам