On Fri, Oct 5, 2012 at 10:54 AM, Dave Howorth
<[email protected]> wrote:
> Jeff Hallock wrote:
>> Hi Dave,
>>
>> 'after' is called after a method call.
>>
>> If you want a block of code to be called every time you set an attribute,
>> you want to use a trigger:
>>
>> has 'foo' => (
>> is => 'rw',
>> trigger => sub {
>> # will be called when setting the attribute via 'new' or via
>> the writer method
>> my ( $self, $newval, $oldval ) = @_;
>> ...
>> }
>> );
>
> That's great. My code works now. Thanks Jeff.
>
> It does seem counter-intuitive. I'd expect
>
> $o = Class->new(attribute => 'value');
>
> to have the same effect as
>
> $o = Class->new(); $o->attribute('value');
>
> Anyway, at least it works and hopefully I'll remember the exception for
> next time.
I actually wouldn't, at least not anymore.
Behavior and state while related are distinct. The call to new() is
passing in the new state for the object that is about to be created, I
wouldn't expect any extra behavior to fire there, and if it did I
would want it to happen explicitly (say via $self->attribute('value')
in BUILD method ... or via a trigger).
I can understand why you would have the expectations you have. I can
also understand why I have the expectations I have. Typically (though
arguably not always) with Moose the defaults should be set to the
least intrusive / most explicit possible. Since there is no way to
unfire an accessor method during construction, the default has to be
to make that behavior explicit.
-Chris