http://www.perlmonks.org?node_id=1019851

morgon has asked for the wisdom of the Perl Monks concerning the following question:

Monks,

assume you have a script that takes input from the command-line and passes that on to a Moose-class Foo, i.e.

use Foo; my ($bar) = @ARGV; my $foo = Foo->new( bar => $bar );
When no bar-value is supplied on the command-line the class should use a default instead (I want to keep the defaults in the class-definition not in the script).

A first try does not what I want:

package Foo; use Moose; has bar => (is => "ro", default => "whatever");
because then when the command-line is empty the constructor is called with "bar" => undef, setting the attribute to undef and not to the intended default.

I usually do this instead:

package Foo; use Moose; has a => (is => "rw"); sub BUILD { my($this, $args)=@_; $this->bar("whatever") unless defined $args->{bar}; }
This does work, instantiating via Foo->new( bar => undef ) sets bar to the default, but the downside is that the default-value is not declared with the attribute but buried in the BUILDer-code and to make this work the attribute has to be "rw".

So I wonder if there is a better way to achieve this - i.e. declaratively defining attribute-defaults for ro-attributes that also get applied when undef is passed in.

Many thanks!