请参阅以下基于 Moose 的 Perl 代码片段:
$BusinessClass->meta->add_attribute($Key => { is => $rorw,
isa => $MooseType,
lazy => 0,
required => 0,
reader => sub { $_[0]->ORM->{$Key} },
writer => sub { $_[0]->ORM->newVal($Key, $_[1]) },
predicate => "has_$Key",
});
我收到错误:
bad accessor/reader/writer/predicate/clearer format, must be a HASH ref at /usr/local/lib/perl5/site_perl/mach/5.20/Class/MOP/Class.pm line 899
错误的原因很清楚: reader 和 writer 必须是函数的字符串名称。
但在这种具体情况下该怎么办呢?我不想为一百个 ORM 字段中的每一个创建一个新函数(这里的 ORM 属性是一个绑定哈希)。所以我不能在这里传递字符串,我需要一个闭包。
因此我的编码需求导致了矛盾。我不知道该怎么办。
以上是真实代码的片段。现在我举一个最小的例子:
#!/usr/bin/perl
my @Fields = qw( af sdaf gdsg ewwq fsf ); # pretend that we have 100 fields
# Imagine that this is a tied hash with 100 fields
my %Data = map { $_ => rand } @Fields;
package Test;
use Moose;
foreach my $Key (@Fields) {
__PACKAGE__->meta->add_attribute($Key => { is => 'rw',
isa => 'Str',
lazy => 0,
required => 0,
reader => sub { $Data{$Key} },
writer => sub { $Data{$Key} = $_[1] },
});
}
运行它的结果是:
$ ./test.pl
bad accessor/reader/writer/predicate/clearer format, must be a HASH ref at /usr/lib/i386-linux-gnu/perl5/5.22/Class/MOP/Class.pm line 899
Class::MOP::Class::try {...} at /usr/share/perl5/Try/Tiny.pm line 92
eval {...} at /usr/share/perl5/Try/Tiny.pm line 83
Try::Tiny::try('CODE(0x9dc6cec)', 'Try::Tiny::Catch=REF(0x9ea0c60)') called at /usr/lib/i386-linux-gnu/perl5/5.22/Class/MOP/Class.pm line 904
Class::MOP::Class::_post_add_attribute('Moose::Meta::Class=HASH(0x9dc13f4)', 'Moose::Meta::Attribute=HASH(0x9dc6b5c)') called at /usr/lib/i386-linux-gnu/perl5/5.22/Class/MOP/Mixin/HasAttributes.pm line 39
Class::MOP::Mixin::HasAttributes::add_attribute('Moose::Meta::Class=HASH(0x9dc13f4)', 'Moose::Meta::Attribute=HASH(0x9dc6b5c)') called at /usr/lib/i386-linux-gnu/perl5/5.22/Moose/Meta/Class.pm line 572
Moose::Meta::Class::add_attribute('Moose::Meta::Class=HASH(0x9dc13f4)', 'af', 'HASH(0x9ea13a4)') called at test.pl line 18
我不知道该怎么做(如何创建“动态”(类似闭包)访问器,而不为 100 个字段中的每个字段编写单独的函数?)