in reply to Psychic Disconnect and Object Systems

but the framers of the system decided this was the normal thing to do

How so? They didn't do anything to hinder what you want to do whatsoever.

around BUILDARGS => sub { my $orig = shift; my $class = shift; ... return $class->$orig(...); };

is slightly more wordy than

sub new { my $class = shift; ... return $class->SUPER::new(...); }

But surely you don't have a problem with that??

(Upd: By the way, you can use the latter, but overriding BUILDARGS allows Moose to do some optimisations. )

Second, what is the point of a read-only attribute? If it can't be set, it will never exist. There must be some "but..." in there.

is => 'ro' is simply a shortcut for reader => $name, and is => 'rw' is simply a shortcut for accessor => $name. It's more "write-once" than "read-only" since neither prevents the the constructor from initialising the attribute, and neither prevents defaults (including those that may be determined from other fields or from external data) from initialising the attribute.

So how do I make attributes that are for internal use?

has attr => ( reader => '_get_attr', writer => '_set_attr', handles => { get_attr => sub { ... }, set_attr => sub { ... }, }, )

(Upd: Sorry, I thought you were asking about internal use accessors. )

Replies are listed 'Best First'.
Re^2: Psychic Disconnect and Object Systems
by educated_foo (Vicar) on Apr 15, 2011 at 17:18 UTC
    It seems like you're being deliberately obtuse in your first two answers.
    How so? They didn't do anything to hinder what you want to do whatsoever.
    The easiest thing to do is to use Moose's automatically-generated new, which does the thing the OP doesn't want. AFAICT "attributes" are the product of confusion between the view that an "object" is a collection of named bits of state, and the view that an "object" is a box to which you send "messages." People want "messages" telling the "object" "give me the value of this named bit of state," so "objects" have "attributes" by default.
    is => 'ro' is simply a shortcut for reader => $name, and is => 'rw' is simply a shortcut for accessor => $name.
    But if you just do
    has 'foo';
    You get read-only attributes by default. The OP's question is "why?" The answer usually leads to a religious war.

    As for internal-use attributes, the OP is wondering what this does:

    package Base; use Moose; has 'x', default => 'Base'; # internal sub foo { print shift->x; } package Child; use Moose; has 'x', default => 'Child'; # also internal package main; Base->new->foo; # "Base" Child->new->foo; # "Base" or "Child"?
    (I would test it myself, but don't have Moose lying around.)

      The easiest thing to do is to use Moose's automatically-generated new,

      So? Unless you are proposing that Moose should automatically build the desired constructor instead (impossible), that's irrelevant. The only thing that matters is how easy it is to build your own constructor, and Moose doesn't hinder that at all.

      But if you just do has 'foo'; You get read-only attributes by default.

      No you don't. You get an error.

      The OP's question is "why?"

      Obviously not. He's asking about is=>'ro'. ro = read-only.

      It seems like you're being deliberately obtuse in your first two answers.

      You have not identified any issues with them.

      As for internal-use attributes, the OP is wondering what this does:

      I did indeed misread that question.

        No you don't. You get an error.
        Here we go... Which error? Well, let's look at the docs...
        has $name|@$names => %options

        This will install an attribute of a given $name into the current class. If the first parameter is an array reference, it will create an attribute for every $name in the list. The %options are the same as those provided by Class::MOP::Attribute, in addition to the list below which are provided by Moose (Moose::Meta::Attribute to be more specific):

        is => 'rw'|'ro'

        The is option accepts either rw (for read/write) or ro (for read only). These will create either a read/write accessor or a read-only accessor respectively, using the same name as the $name of the attribute.

        If you need more control over how your accessors are named, you can use the reader, writer and accessor options inherited from Class::MOP::Attribute, however if you use those, you won't need the is option.

        Looks like "has" takes a scalar and a hash of options, and "is" doesn't seem to be a mandatory option. You've got me stumped!
Re^2: Psychic Disconnect and Object Systems
by John M. Dlugosz (Monsignor) on Apr 18, 2011 at 01:42 UTC
    I don't recall reading about accessor, just reader and writer.

    So, the built-in 'new' logic and the application of default don't go through the normal set function, so lack of one doesn't bother it.

      I don't recall reading about accessor, just reader and writer.

      $o->an_accessor('foo'); $foo = $o->an_accessor(); $o->a_writer('foo'); $foo = $o->a_reader();

      So, the built-in 'new' logic and the application of default don't go through the normal set function, so lack of one doesn't bother it.

      Correct.