是否有任何Perl模块可以通过默认配置和可选配置的hashref设置对象?

是否有任何Perl模块可以通过默认配置和可选配置的hashref设置对象?,perl,cpan,Perl,Cpan,我发现自己在反复编写和重写以下代码: 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};

我发现自己在反复编写和重写以下代码:

 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.
 }
在我制作自己的模块来实现这一点之前,我只是想知道CPAN上是否已经有类似的东西?我只想要上面这个非常简单的功能,因此建议使用Moose不是这个问题的合适答案。

支持属性的默认值,例如:

has 'foo' => ( is => 'rw', isa => 'Int', default => 42 );
但是,如果你不想沿着驼鹿路线走下去,一个更简单的方法就是:

sub new { 
    my ( $package, %config ) = @_;

    my %defaults = ( x => 'a', y => 'b' );

    my $self = { %defaults, %config };

    # error checking here

    return bless $self, $package;
}

由于在散列初始化中指定相同的散列键两次将超过第一个,因此
%config
中的任何键都将简单地覆盖
%defaults

中的键。如果您已经在模块中使用Moose,则可以通过组合和来获得此行为。配置文件可以包含默认值,然后通过将这些值传递给构造函数,根据需要覆盖任何内容:

my $obj = Class->new_with_options(configfile => "myconfig.yaml", key1 => 'val', key2 => 'val');

package Class;
use Moose;
with 'MooseX::Getopt::Strict',
    'MooseX::SimpleConfig';

has configfile => (
    is => 'ro', isa => 'Str',
    traits => ['Getopt'],
    documentation => 'File containing default configs',
    lazy => 1,
    default => sub { File::Spec->catfile($base_dir, 'my_default_config.yaml') },
);

has [ qw(key1 key2) ] => (
    is => 'ro', isa => 'Str',
);
可能会有所帮助。它允许您删除
%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;
输出:

--- !!perl/hash:My::Class x: 1 y: b --- !!perl/hash:My::Class x:1
y:B谢谢你给我双倍哈希的小费。我当然也需要检查%config中的杂散内容。双重散列技巧看起来很不错,似乎对我很有效,但令我惊讶的是,perldata实际上没有说明当一个散列被分配到包含重复键的列表时会发生什么。您有相关文档吗?@random,在
perlfaq4
中有简要介绍,请参阅“如何从两个哈希中获取唯一密钥?”的?谢谢。Perldata应该说明这是如何处理的,如果我能找出谁维护了文档,我会给他们一个补丁。好的,我接受没有真正的答案,所以接受提及Params::Validate,这可能是最接近我所问的问题。