Perl: Добавление писателя в класс Moose запрещает доступ к атрибутам
Я только начал изучать Moose, и я создал очень простой класс. Вот мой код:
Person.pm
package Person;
use Moose;
has fname => (
is => 'rw',
isa => 'Str',
reader => 'getFirstName',
);
has lname => (
is => 'rw',
isa => 'Str',
reader => 'getLastName',
writer => 'setLastName',
);
sub printName {
my $self = shift;
print $self->getFirstName() . " " . $self->getLastName(), "\n";
}
no Moose;
__PACKAGE__->meta->make_immutable;
person.pl
#!/usr/bin/env perl
use strict;
use warnings;
use Person;
my $person = Person->new(fname => 'jef', lname => 'blah',);
print $person->fname, $person->lname, "\n";
$person->setLastName('bleh');
$person->getName();
Где этот код умирает, строка 8. Он напечатает атрибут имени, но скулит о lname Can't locate object method "lname" via package "Person" at ./person.pl line 8.
Теперь, если я достану writer
в lname все хорошо, но как это имеет смысл? Я понимаю, что могу использовать созданные мной геттеры, но мне любопытно, почему писатель отказывает мне в доступе к самому атрибуту? Думаю, я чего-то не понимаю...
1 ответ
lname
не "сам атрибут", потому что fname
также не "сам атрибут". Это тоже функция, которая возвращает атрибут. Писая читателя и писателя, вы выбираете, что вы предпочитаете, чтобы эти субмарины были названы, вот и все.
Вызов подпрограммы с неправильным именем не удается раньше. Старый способ Perl OO, состоящий из благословенных хэшей и полей-членов в качестве ключей хеш-функции, приводит к выживаемым ошибкам времени выполнения, когда имена атрибутов были введены неправильно. Идея создания сабвуферов для аксессоров состоит в том, чтобы рано и полностью потерпеть неудачу. Поскольку хеш может хранить любую строку, благословленный объект может вызывать только определенный набор функций, определенных для класса или унаследованных.
Согласно Руководству,
Каждый атрибут имеет один или несколько методов доступа. Метод доступа позволяет вам читать и записывать значение этого атрибута для объекта.
По умолчанию метод доступа имеет то же имя, что и атрибут. Если вы объявили свой атрибут как ro, то ваш метод доступа будет доступен только для чтения. Если вы объявили его как rw, вы получите аксессор чтения-записи. Просто.
Учитывая приведенный выше пример Person, теперь у нас есть единственный метод доступа first_name, который может читать или записывать значение атрибута first_name объекта Person.
Если вы хотите, вы также можете явно указать имена методов, которые будут использоваться для чтения и записи значения атрибута. Это особенно удобно, когда вы хотите, чтобы атрибут был общедоступным, но только для частной установки. [курсив мой]