Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid

Passing params, as a hash, to moose

by neilwatson (Priest)
on Oct 13, 2012 at 01:25 UTC ( #998808=perlquestion: print w/replies, xml ) Need Help??
neilwatson has asked for the wisdom of the Perl Monks concerning the following question:


I have a moose question. I'm still new to moose. Normally I would pass parameters to a new object thusly.

my $ob = MyModule->new( colour => $colour, shape => $shape, );

Suppose that colour and shape are arguments and that they are optional. It seems that if no argument is given via my program the value is ''. This seems to confuse my classes on the moose side where it fails to set the default. My thought was to build the parameter hash before hand so as to pass only the arguments that are defined.

if ( $colour ) { $param{'colour'} = $colour }; if ( $shape ) { $param{'shape'} = $shape }; my $ob = MyModule->new( %param );

I tried this but nothing seems to make it to moose. Am I on the right track? Is there better way?

Neil Watson

Replies are listed 'Best First'.
Re: Passing params, as a hash, to moose
by frozenwithjoy (Priest) on Oct 13, 2012 at 04:53 UTC

    So, if I'm understanding your problem correctly, you are building your object with undefined attributes and even if you have defaults set for the attributes, they still get set to undef, right?

    I deal with this by using MooseX::UndefTolerant, whose brief description is: "Make your attribute(s) tolerant to undef initialization". One more thing: for this to work, it seems that you need to make your attribute lazy. Below is an example.

    package test_undef; use Moose; use MooseX::UndefTolerant; has 'language' => ( is => 'rw', isa => 'Str', default => 'Perl', lazy => 1, ); no Moose; __PACKAGE__->meta->make_immutable;

    #!/usr/bin/env perl use strict; use warnings; use feature 'say'; use test_undef; use Getopt::Long; my $language; GetOptions( "language=s" => \$language, ); my $test = test_undef->new( 'language' => $language, ); say $test->language;

    If I call ./ without the --language option (or w/o defining language any other way), the output is: Perl (the default I set for the language attribute).

Re: Passing params, as a hash, to moose
by mbethke (Hermit) on Oct 13, 2012 at 02:22 UTC

    That's a lot of work for the calling code. I'm not a Moose expert either but I'd use a BUILDARGS method, that's significantly shorter and cleaner already:

    sub BUILDARGS { my ($class, %args) = @_; defined $args{colour} and '' ne $args{colour} or $args{colour} = ' +#123'; return \%args; }
    Like this you only have to write the whole stuff once instead of once for every ->new

Re: Passing params, as a hash, to moose
by kcott (Chancellor) on Oct 13, 2012 at 09:47 UTC

    G'day Neil,

    Without seeing your module code, I can't say specifically what's wrong. I suspect your has functions have one or more of required, lazy or default incorrectly set up. See Moose - EXPORTED FUNCTIONS for details. The following works for me.

    Moose module:

    package pm_moose_default_params; use Moose; has colour => ( is => 'rw', isa => 'Str', required => 0, lazy => 1, default => 'red', ); has shape => ( is => 'rw', isa => 'Str', required => 0, lazy => 1, default => 'circle', ); no Moose; __PACKAGE__->meta->make_immutable;

    Calling script:

    #!/usr/bin/env perl use 5.010; use strict; use warnings; use Getopt::Long; use pm_moose_default_params; my $colour = ''; my $shape = ''; GetOptions('colour=s' => \$colour, 'shape=s' => \$shape); say "Option --colour = $colour"; say "Option --shape = $shape"; my %param; $param{colour} = $colour if $colour; $param{shape} = $shape if $shape; say "Param $_ = $param{$_}" for keys %param; my $object = pm_moose_default_params::->new(%param); say 'Moose colour = ', $object->colour; say 'Moose shape = ', $object->shape;

    Some sample runs:

    $ Option --colour = Option --shape = Moose colour = red Moose shape = circle $ --colour=blue Option --colour = blue Option --shape = Param colour = blue Moose colour = blue Moose shape = circle $ --shape=square Option --colour = Option --shape = square Param shape = square Moose colour = red Moose shape = square $ --colour=blue --shape=square Option --colour = blue Option --shape = square Param colour = blue Param shape = square Moose colour = blue Moose shape = square

    -- Ken

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://998808]
Approved by davido
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (9)
As of 2017-06-24 14:56 GMT
Find Nodes?
    Voting Booth?
    How many monitors do you use while coding?

    Results (559 votes). Check out past polls.