代码之家  ›  专栏  ›  技术社区  ›  user181548

是否有任何Perl模块可以从默认配置加上可选配置的hashRef来设置对象?

  •  6
  • user181548  · 技术社区  · 15 年前

    我发现自己反复地写和重写以下类型的代码:

     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上是否已经有类似的东西?我只是希望上面的功能非常简单,所以建议使用驼鹿并不是这个问题的合适答案。

    3 回复  |  直到 15 年前
        1
  •  4
  •   Sinan Ünür    15 年前

    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;
    

    输出:

    --- !!perl/hash:My::Class
    x: 1
    y: b
        2
  •  11
  •   friedo    15 年前

    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 .

        3
  •  3
  •   Ether    15 年前

    如果您已经在模块中使用moose,那么可以通过组合 MooseX::Getopt MooseX::SimpleConfig . 配置文件可以包含默认值,然后通过将这些值传递给构造函数来根据需要重写任何内容:

    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',
    );
    
    推荐文章