Делает ли установка имени писателя для атрибута Moo только для чтения сделать его чтение-запись? - PullRequest
0 голосов
/ 05 мая 2018

Я изучаю Му и столкнулся с этим основным вопросом. Если я задаю имя доступа или имя записывающего лица для атрибута только для чтения, атрибут становится доступным для записи. Предполагает ли аксессор или писатель, что атрибут доступен для записи, даже если он установлен только для чтения (is => 'ro')?

Вот код класса:

#!/home/fl/perl5/perlbrew/perls/perl-5.26.1/bin/perl
package MooPerson;
use Moo;
use namespace::clean;

has firstname => (
    is     => 'rw',
    reader => 'get_firstname',
    writer => 'set_firstname',
);

has surname => (
    is      => 'ro',
    reader  => 'get_surname',
    writer  => 'set_surname',
);

sub get_fullname {
    my ($self) = @_;
    my $firstname = $self->get_firstname;
    my $surname   = $self->get_surname;
    return "$firstname $surname";
}
1;

Код объекта:

#!/home/fl/perl5/perlbrew/perls/perl-5.26.1/bin/perl
use lib 'lib';
use MooPerson;
use feature 'say';
use strict;
use warnings;

say "new object person";
my $person = MooPerson->new(
    firstname => 'Homer',
    surname   => 'Simpson',
);

say "person->get_firstname: " . $person->get_firstname();
say "person->get_surname: " . $person->get_surname();

say "\nchange firstname and surname";
$person->set_firstname('Aristotle');
$person->set_surname('Amadopolis');

say "person->get_firstname: " . $person->get_firstname();
say "person->get_surname: " . $person->get_surname();

Результат:

fl@dancertest:~/perltest$ ./firstMoo.pl
new object person
person->get_firstname: Homer
person->get_surname: Simpson

change firstname and surname
person->get_firstname: Aristotle
person->get_surname: Amadopolis

То же самое происходит при использовании средства доступа. (is => 'ro') работает только если я использую автоматически сгенерированное имя доступа, в данном случае "фамилия".

Это предполагаемое поведение или ошибка?

Большое спасибо.

Ответы [ 2 ]

0 голосов
/ 06 мая 2018

Да, потому что is не делает ничего доступным только для чтения; он просто создает метод доступа.

  • is => 'rw' - это просто сокращение для accessor => 'attribute_name'.
  • is => 'ro' - это просто сокращение для reader => 'attribute_name'.

Если вы укажете writer, вы сможете писать в атрибут, даже если вы использовали is => 'ro'.

Если я хочу публичного читателя и частного / защищенного писателя, я использую

has surname => (
    reader => 'get_surname',
    writer => '_set_surname',
);

или

has surname => (
    reader => 'surname',
    writer => '_set_surname',
);
0 голосов
/ 05 мая 2018

Я думаю, что это предполагаемое поведение, а не ошибка. Как только вы создаете средство записи с writer => 'set_surname', атрибут перестает быть доступным только для чтения в том смысле, что теперь вы можете изменять его через средство записи. Если вам нужен частный писатель и общедоступный читатель, вы можете поставить подчеркивание перед именем писателя, чтобы указать, что оно является внутренним по отношению к классу:

has surname => (
    is      => 'ro',
    reader  => 'get_surname',
    writer  => '_set_surname',
);

Помещение подчеркивания перед именем метода является распространенным способом в Perl, чтобы дать подсказку пользователю, что атрибут предназначен только для частного использования.

...