我发现自己反复编写和重写以下类型的代码:
my %default = (x => "a", y => "b");
sub new
{
my ($package, $config) = @_;
my $self = {%default};
for my $k (keys %default) {
$self->{$k} = $config->{$k} if defined $config->{$k};
}
for my $k (keys %$config) {
if (! exists $default{$k}) {
carp "Unknown config option $k\n";
}
}
bless $self;
# etc. etc.
}
Run Code Online (Sandbox Code Playgroud)
在我创建自己的模块之前,我只是想知道CPAN上是否还有这样的东西?我只是想要这个非常简单的上述功能,所以建议使用Moose不是这个问题的合适答案.
fri*_*edo 11
Moose支持属性的默认值,例如:
has 'foo' => ( is => 'rw', isa => 'Int', default => 42 );
Run Code Online (Sandbox Code Playgroud)
但是如果你不想沿着穆斯路线走下去,那么实现你想要的更简单的方法是:
sub new {
my ( $package, %config ) = @_;
my %defaults = ( x => 'a', y => 'b' );
my $self = { %defaults, %config };
# error checking here
return bless $self, $package;
}
Run Code Online (Sandbox Code Playgroud)
由于在散列初始化中指定相同的散列键两次将破坏第一个散列键,因此任何键都%config将覆盖其中的那些键%defaults.
Params::Validate可能会有所帮助。它将允许您删除%defaults哈希并为每个(可能是可选的)参数指定默认值。
此外,您可以使用 使其变得不那么冗长map。当然,这会默默地忽略无效的参数。
#!/usr/bin/perl
package My::Class;
use strict; use warnings;
my %defaults = ( x => 'a', y => 'b' );
sub new {
my $class = shift;
my ($args) = @_;
my $self = {
%defaults,
map {
exists $args->{$_} ? ($_ => $args->{$_}) : ()
} keys %defaults,
};
return bless $self, $class;
}
package main;
use strict; use warnings;
my $x = My::Class->new({ x => 1, z => 10});
use YAML;
print Dump $x;
Run Code Online (Sandbox Code Playgroud)
输出:
--- !!perl/hash:我的::类 x:1 y:b