Я играю с некоторым кодом, в котором объединение кодовых ссылок с переменными имеет смысл, но использование полноценного OOD - нет. По сути, я пишу функциональный код, но прибегаю к нескольким структурам в стиле ОО, чтобы инкапсулировать вещи, в которых имеет смысл состояние действительно . Снаружи это в основном функции без состояния.
Использование Moose для этого было бы равносильно наказанию коллег, которые иногда опаздывали, с помощью автоматической винтовки: совершить излишнее убийство несколькими способами. Так что избавьте меня от 'ALL PERL OOP ДОЛЖНЫ ИСПОЛЬЗОВАТЬ БОЛЬШЕ СЕЙЧАС !!!' мантра.
Итак, я побежал в хороший старый класс blessed-hashref, чтобы выполнить мои ставки, но обнаружил, что написание кода доступа - это боль, и я не хотел использовать нестандартные модули для того, что по сути является очень тривиальной задачей. .
После перемещения по страницам на http://perldoc.perl.org, Я наткнулся на Class :: Struct и Object :: Accessor, которые являются основными модулями, облегчающими создание атрибутов OO. Отлично, хотя я. Но ...
Object :: Accessor показался мне идеальным билетом, но я просто использовал его подпрограмму mk_accessor в конструкторе, которая не казалась столь же элегантной, как использование Class :: Struct во время компиляции, который также написал мой конструктор по умолчанию для меня. В общем, я предпочел Class :: Struct объекту :: Accessor, потому что позволял немного меньше шаблонного и имел более декларативный синтаксис.
Сравнение с использованием тривиальных примеров, если вам интересно:
Использование Class :: Struct:
#!/usr/bin/perl
use 5.014;
use autodie;
use strict;
use warnings;
package Account {
use Class::Struct
first_name => '$',
last_name => '$',
age_in_years => '$',
activated => '$',
;
sub formatted {
my ($self_ref) = @_;
return sprintf
"First name: %s\n" .
"Last name: %s\n" .
"Age in Years: %d\n" .
"Activated: %s",
$self_ref->first_name,
$self_ref->last_name,
$self_ref->age_in_years,
$self_ref->activated || 'No'
;
}
}
my $account = Account->new;
$account->first_name('Tom');
$account->last_name('Smith');
$account->age_in_years(16);
$account->activated('Yes');
say $account->formatted
Использование Object :: Accessor:
use 5.014;
use autodie;
use strict;
use warnings;
package Account {
use base 'Object::Accessor';
sub new {
my ($type) = @_;
my $self = bless { }, $type;
$self->mk_accessors(qw(first_name last_name age_in_years activated));
return $self;
}
sub formatted {
my ($self_ref) = @_;
return sprintf
"First name: %s\n" .
"Last name: %s\n" .
"Age in Years: %d\n" .
"Activated: %s",
$self_ref->first_name,
$self_ref->last_name,
$self_ref->age_in_years,
$self_ref->activated || 'No'
;
}
}
my $account = Account->new;
$account->first_name('Tom');
$account->last_name('Smith');
$account->age_in_years(16);
$account->activated('Yes');
say $account->formatted;
Действительно, оба вполне приемлемы, но первый немного более чистый IMO. Я хочу знать, могу ли я использовать Class :: Struct без указания ограничений типа?
Мне они не нужны в контексте, которым я их использую, но, похоже, я не могу просто добавить средства доступа без указания типовых ограничений рядом с ними. Без сомнения, я теряю производительность из-за ненужной проверки типов.
Если это невозможно, я просто буду придерживаться Object :: Accessor. Но возможны ли средства доступа без ограничений типа с Class :: Struct?