in reply to Using ArrayRef data members in Moose

I want to reopen this thread about Moose::AttributeHelpers::Collection::Array because I just don't get it!

Will someone who speaks in plain language please explain to me exactly what this does? Exactly what it is saying to Perl or to Moose?

provides => { 'push' => 'add_things' },

When I look at this code (and elsewhere...) I do not see the word “push!” I see people using a method, “add_things,” plenty of times, but that looks like an ordinary method-call ... but what sort of stale-tasting “sugar” is this?

My hand is once-again poised in front of my forehead, ready to slap... (Whack! “Doh!!”) :-)

Replies are listed 'Best First'.
Re^2: Using ArrayRef data members in Moose
by Fletch (Bishop) on Jan 23, 2009 at 17:51 UTC

    That's saying that the class' instances have a method add_things which when called will push its arguments on to the end of the arrayref instance variable in question. It's sugar for something like this:

    package Foo; use Moose; has 'some_method' => ( is => 'ro', isa => 'ArrayRef', default => sub { +[] }, ); sub add_things { my $self = shift; push @{ $self->some_member }, @_; }

    The provides makes it write methods which perform that operation (be it push, or pop, or keys, or . . .) on the instance's member in question.

    Update: Minor wording tweaks and removed metaclass declaration from sample code since it's superfluous.

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.

Re^2: Using ArrayRef data members in Moose
by locked_user sundialsvc4 (Abbot) on Jan 23, 2009 at 17:57 UTC

    Well, whaddaya know...

    Whack! “Doh!!”

    I figured it out!

    It seems that the magic is this:   this definition adds new methods, to the object, not the array attribute, which have the “magical effect” of doing the appropriate operation to the appropriate attribute... automagically knowing both what the attribute is, and what to do with it.

    What was throwing me off, for the longest time, was this incorrect code:

     $n = $object->items->num_items();  ##INCORRECT
    which was giving me the very mysterious error:
    # died: Can't call method "num_items" on unblessed reference...

    Which is incorrect because the method is attached to the object. Oh... I get it... Gee, it's even seriously cool...

    Therefore, this works:

     $n = $object->num_items();  ##CORRECT

      I know this is OLD! But i want to post this example, that works
      use MooseX::Declare; ... ... ... has 'error_log' => ( is => 'rw', isa => 'ArrayRef', default => sub { [] } ); ... ... ... method register_error { shift; my $s_message = shift; return unless defined $s_message; my @a_temp = ( $s_message ); $self->error_log->push ($s_message); return $self->error_log->length; }
      self->error_log->push does not work until i assign a "default" for the array.
      I know this is OLD! But i want to post this example, that works
      use MooseX::Declare; ... ... ... has 'error_log' => ( is => 'rw', isa => 'ArrayRef', default => sub { [] } ); ... ... ... method register_error { shift; my $s_message = shift; return unless defined $s_message; $self->error_log->push ($s_message); return $self->error_log->length; }
      self->error_log->push does not work until i assign a "default" for the array.
        self->error_log->push does not work until i assign a "default" for the array.

        Actually it won't work then either until you add a use Moose::Autobox as well.

        -stvn