Как я могу получить доступ только для чтения атрибутов объектов Moose? - PullRequest
5 голосов
/ 01 октября 2010

Я абсолютный новичок в Moose, и до сих пор я прочитал Moose и большую часть поваренной книги .

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

package MyRange;

use Moose;
use namespace::autoclean;

has [ 'start', 'end' ] => (
    is       => 'ro',
    isa      => 'Int',
    required => 1,
);

__PACKAGE__->meta->make_immutable;

1;

Тогда:

use MyRange;    
my $br = MyRange->new(
    start                => 100,
    end                  => 180
);

Теперь я могу получить доступ к своим полям, например, с помощью $br->{start}, но я также могу изменить их (хотя они «только для чтения»), например, используя $br->{start}=5000. Я также могу добавить новые ключи, такие как $br->{xxx}=111.

Я что-то упустил? Разве объект не защищен каким-либо образом? В чем смысл ro?

Ответы [ 2 ]

14 голосов
/ 01 октября 2010

Когда вы сказали is => 'ro', вы сказали Moose создать средства доступа только для чтения, то есть метод чтения.Вы называете это как

$br->start;

или

$br->end;

Установка атрибутов с использованием этих методов приведет к исключению:

$br->start(42);

Если вы использовали is => 'rw', тогда вышеприведенное сработает и обновит значение атрибута.

То, что вы делаете, это прямой хеш-доступ к объекту, который нарушает инкапсуляцию и не должен быть необходим при использовании Moose.

Руководство Moose, то есть все документы в пространстве имен Moose::Manual, объясняют это подробно.Хорошей отправной точкой для таких вопросов, вероятно, является Moose::Manual::Attributes.

3 голосов
/ 01 октября 2010

Когда вы получаете доступ к атрибуту с помощью $br->{start}, вы обходите метод доступа и обращаетесь непосредственно к базовой реализации Moose.Вы можете сделать это, но вы не должны.Кроме того, если Moose изменит реализацию, ваш код сломается.

Вместо этого вы должны получить доступ к атрибуту, используя метод доступа:

my $start = $br->start;

Когда вы говорите, что атрибутом является 'RO',это означает, что вам не разрешено изменять значение атрибута с помощью метода доступа:

$br->start(32);
...