Is there any Perl module for setting an object from the default configuration plus hashref of additional configurations?

I find that I write and rewrite the following code many times:

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

Before I make my own module for this, I just wonder if there is anything already in CPAN? I just want this very simple functionality above, so the proposal to use the Muses is not a suitable answer to this question.

+6
perl cpan
source share
3 answers

Params :: Validate may be helpful. This will allow you to remove the hash of %defaults and specify default values ​​for each (possibly optional) parameter.

In addition, you can make this a bit less verbose using map . Of course, it will silently ignore invalid arguments.

 #!/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; 

Output:

  --- !! perl / hash: My :: Class
 x: 1
 y: b 
+4
source share

Moose supports default values ​​for attributes, for example:

 has 'foo' => ( is => 'rw', isa => 'Int', default => 42 ); 

But if you do not want to follow the Muse route, an easier way to achieve what you want:

 sub new { my ( $package, %config ) = @_; my %defaults = ( x => 'a', y => 'b' ); my $self = { %defaults, %config }; # error checking here return bless $self, $package; } 

Since specifying the same hash key twice in the hash initialization will hit the first one, any keys in %config will simply override those in %defaults .

+11
source share

If you already use Moose in your modules, you can get this behavior by combining MooseX :: Getopt and MooseX :: SimpleConfig . Your configuration file may contain default values, and then you override something as needed, passing these values ​​to the constructor:

 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', ); 
+3
source share

All Articles