我正在寻找一些代码,其中使用变量捆绑coderefs是有意义的,但使用完整的OOD则没有。基本上,我正在编写功能代码,但是选择少数OO风格的结构来封装有状态真正有意义的东西。除此之外,它主要是无国家的功能。
使用Moose就像是偶尔训练一个带有自动步枪的迟到的同事:完全矫枉过正的方式多于一个。所以请不要忘记'ALL PERL OOP必须现在使用MO!'曼陀罗。
所以我跑到了好的'blessed-hashref类来做我的出价,但发现编写访问器代码很痛苦,并且不想为非常简单的任务引入非标准模块
在浏览http://perldoc.perl.org上的页面之后,我偶然发现了Class :: Struct和Object :: Accessor,它们是简化OO属性构建的核心模块。完美,我。但...
Object :: Accessor似乎是完美的票,但我只是在构造函数中使用它的mk_accessor子,它似乎没有使用编译时Class :: Struct那么优雅,它也编写了我的默认构造函数为了我。总而言之,我更喜欢Class :: Struct to Object :: 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?
是否可以使用非类型约束的访问器答案 0 :(得分:1)
我更喜欢Class::Struct来完成任务。我通常只使用标量,它们没有验证,你可以存储任何东西(如arrayref或hashref)。
另一个优点是您选择的语法是基于数组制作对象,这些数组较小且访问速度更快。没什么戏剧性的,但是如果你有很多对象,它可以提供帮助。
package Account;
use Class::Struct
map { $_ => '$' } qw(
first_name
last_name
age_in_years
activated
items
);
package main;
my $acc = Account->new(
first_name => 'John',
last_name => 'Doe',
items => ['a' .. 'z']
);