7

I would like to simply declare a read only attribute in Moose that cannot be initialized in a call to new. So after declaring the following:

package SOD::KuuAnalyze::ProdId;

use Moose;

has 'users' => (isa => 'ArrayRef[Str]', is => "ro");

1;

I do not want the following to work:

my $prodid = SOD::KuuAnalyze::ProdId->new(users => ["one", "two"]);
brian d foy
  • 129,424
  • 31
  • 207
  • 592
ennuikiller
  • 46,381
  • 14
  • 112
  • 137

2 Answers2

15

Use the init_arg attribute configuration (see "Constructor parameters" in Moose::Manual::Attributes):

package SOD::KuuAnalyze::ProdId;
use Moose;

has 'users' => (
    isa => 'ArrayRef[Str]', is => "ro",
    init_arg => undef,    # do not allow in constructor
);
1;
Ether
  • 53,118
  • 13
  • 86
  • 159
  • 1
    This works nicely, thank you. However it fails silently. Is there a way to get it to throw an error whilst attempting ProdId->new(users => ['one','two'])? – ennuikiller Nov 29 '09 at 14:00
  • 4
    If you use MooseX::StrictConstructor, module construction will fail if any invalid or disallowed arguments are passed to the constructor. I use it in almost all my Moose classes (for the rest, I use MooseX::SlurpyConstructor which grabs all arguments that aren't used by attributes). – Ether Nov 29 '09 at 17:26
4

How about

package SOD::KuuAnalyze::ProdId;

use Moose;

has 'users' => ( isa => 'ArrayRef[Str]', is => 'ro', init_arg => undef, default => sub { [ 'one', 'two' ] } );

Setting the init_arg to undef seems to be necessary to disallow setting the attribute from the constructor.

friedo
  • 65,762
  • 16
  • 114
  • 184