in reply to Re: Exporting constants from a Moo role
in thread Exporting constants from a Moo role

You'd probably also want to prevent people from overriding the constant using:

my $obj = MyClass->new(INDEX_FOO => 43);

To do this, use:

has 'INDEX_FOO'=> ( is => 'ro', default => 42 init_arg => undef, );

But by that point, you have to ask, why not just do this?

sub INDEX_FOO () { 42 }

Replies are listed 'Best First'.
Re^3: Exporting constants from a Moo role
by 1nickt (Canon) on Aug 02, 2018 at 21:40 UTC

    Thanks Toby! init_arg => undef is a new one on me. Why do you need to declare a default value (or what is the point) when you use that parameter to the attribute?

    I quite often use simple subs for constants if only because the syntax to declare them is simpler and shorter. I guess the author of this code (which is used to access the elements of a work queue job) prioritized simpler and shorter syntax at the calling end, preferring $self->job->[INDEX_FOO] to $self->job->[ $self->INDEX_FOO ] ...

    I think I like the solution you showed in your other reply. Thanks again!


    The way forward always starts with a minimal test.

      init_arg is used to tell Moo what key will get passed to the constructor for that attribute.

      use v5.16; package Person { use Moo; has "nick-name" => ( is => "ro", init_arg => "nick", reader => "nick_name", ); }; my $robert = Person->new(nick => "Bob"); # init_arg say $robert->nick_name; # reader say $robert->{"nick-name"}; # attribute name (direct +hashref access)

      Setting init_arg to undef means that the attribute cannot be passed to the constructor at all. (And if the attribute is also read-only, so there's no writer method, you should probably be setting a default for the attribute too!)

      (And this is not Moo-specific. Moose and Mouse have the exact same features.)