所以我熟悉Perl中的fields pragma,它可以用来限制存储在类中的字段:
package Fruit;
use fields qw( color shape taste );
sub new {
my ( $class, $params ) = @_;
my $self = fields::new( $class ) unless ref $class;
foreach my $name ( keys %$params ) {
$self->{ $name } = $params->{ $name };
}
return $self;
}
一旦我在顶部声明了字段,我怎么能回到列表,说因为我想动态生成访问器? keys %FIELDS
是唯一的方法吗?
其次,是否有一种更有效的方法来预先填充构造函数中的字段,而不是像上面那样循环并分配每个参数?
答案 0 :(得分:6)
如果您正在使用Perl 5.10及更高版本(实际上是5.9及更高版本,但我不计算开发版本),fields
会创建一个受限制的哈希。有关限制哈希的信息,请参阅Hash::Util。
要使所有字段都可用于受限制的哈希,请使用legal_keys
或legal_ref_keys
函数:
use Hash::Util qw( legal_ref_keys );
my $froot = Fruit->new();
my @attribs = legal_ref_keys($froot);
你可以做很多事情来自动生成你的方法:
%FIELDS
哈希,以便在编译时或通过AUTOLOAD生成方法。 更多问题 - 假设未发布的fields
pragma位将保留。选项4:
package Fruit;
use strict;
use warnings;
my @ATTRIBUTES;
BEGIN { @ATTRIBUTES = qw( color shape taste ); }
use fields @ATTRIBUTES;
for my $attrib ( @ATTRIBUTES ) {
my $getset = sub {
my $self = shift;
if( @_ ) {
$self->{$attrib} = shift;
}
return $self->{$attrib};
};
{ no strict 'refs';
*{$attrib} = $getset;
}
}
sub new {
my ( $class, $params ) = @_;
my $self = fields::new( $class ) unless ref $class;
foreach my $name ( keys %$params ) {
$self->{ $name } = $params->{ $name };
}
return $self;
}
选项5。
package Fruit;
use Moose;
has 'color' => (
is => 'rw',
isa => 'Str',
);
has 'shape' => (
is => 'rw',
isa => 'Str',
);
has 'taste' => (
is => 'rw',
isa => 'Str',
);
答案 1 :(得分:1)
在fields
pragma正在使用的位置创建的每个对象都将定义这些字段(并且只定义那些字段),即使您没有初始化它们也是如此。因此,您不必担心不推荐使用%FIELDS
表。
DB<1> $apple = Fruit->new( {qw(color red shape apple taste like-an-apple)} )
DB<2> p join' ',keys %$apple
color taste shape
DB<3> $kiwi = Fruit->new()
DB<4> p join' ',keys %$kiwi
color taste shape
答案 2 :(得分:1)
现在我拥有的最佳解决方案是这样的:
# Return the fields for this object
sub fields {
my ( $self ) = @_;
my $class = ref( $self ) || $self;
return [ keys %{ "${class}::FIELDS" } ];
}