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

6 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};
      }
      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.

  • @random,在'perlfaq4`中有一个简短的提及,请参阅"如何从两个哈希中获取唯一键?" 在http://perldoc.perl.org/perlfaq4.html#How-can-I-get-the-unique-keys-from-two-hashes? (3认同)

Sin*_*nür 4

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