Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
attribute initialisation and after
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  7 messages - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Dave Howorth  
View profile  
 More options Oct 5 2012, 10:30 am
Newsgroups: perl.moose
From: dhowo...@mrc-lmb.cam.ac.uk (Dave Howorth)
Date: Fri, 05 Oct 2012 15:24:04 +0100
Local: Fri, Oct 5 2012 10:24 am
Subject: attribute initialisation and after
I wrote a Moose class and the class 'has' an attribute. The attribute
also has an 'after' modifier.

But when I create an object of the class and supply an initial value for
the attribute to the 'new' method, it appears that the 'after' modifier
is not called. It is called if I later access the attribute.

My expectation is that initialisation of an attribute would invoke the
attribute's setter and the modifier, so reality doesn't match my
expectation - is there something that explains why reality is as it is
so I can adjust my expectation?

Cheers, Dave


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Jeff Hallock  
View profile  
 More options Oct 5 2012, 10:45 am
Newsgroups: perl.moose
From: JHall...@WBandA.com (Jeff Hallock)
Date: Fri, 5 Oct 2012 14:27:34 +0000
Local: Fri, Oct 5 2012 10:27 am
Subject: RE: attribute initialisation and after
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 ) = @_;
                ...
        }
);

- Jeff


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Dave Howorth  
View profile  
 More options Oct 5 2012, 11:00 am
Newsgroups: perl.moose
From: dhowo...@mrc-lmb.cam.ac.uk (Dave Howorth)
Date: Fri, 05 Oct 2012 15:54:15 +0100
Local: Fri, Oct 5 2012 10:54 am
Subject: Re: attribute initialisation and after

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.

Cheers, Dave


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Chris Prather  
View profile  
 More options Oct 5 2012, 12:30 pm
Newsgroups: perl.moose
From: ch...@prather.org (Chris Prather)
Date: Fri, 5 Oct 2012 12:16:21 -0400
Local: Fri, Oct 5 2012 12:16 pm
Subject: Re: attribute initialisation and after
On Fri, Oct 5, 2012 at 10:54 AM, Dave Howorth

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


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Dave Howorth  
View profile  
 More options Oct 8 2012, 5:45 am
Newsgroups: perl.moose
From: dhowo...@mrc-lmb.cam.ac.uk (Dave Howorth)
Date: Mon, 08 Oct 2012 10:32:28 +0100
Local: Mon, Oct 8 2012 5:32 am
Subject: Re: attribute initialisation and after

I'm afraid I don't understand what it is you wouldn't, given that it
seems you would have before but won't now?

> 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).

The call to new is passing in a new value for an attribute.
The call to the mutator is passing in a new value for an attribute.
I expect them to treat the new value in the same way in both cases.

> I can understand why you would have the expectations you have. I can
> also understand why I have the expectations I have.

I don't understand why you have the expectations you have. I'm not even
sure I understand what those expectations are. Is there any
documentation that explain what expectations are sensible to have for Moose?

(one thing I've noticed is that the documents start out by giving basic
explanations of how to construct objects, and then more complicated
explanations of what can be constructed, without giving any examples at
all of how to use the objects.)

> 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.

I'm not clear what defaults have to do with it? Nor what would
constitute unfiring an accessor? Or why you would want to do it?

Confused, Dave


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Jesse Luehrs  
View profile  
 More options Oct 8 2012, 11:15 am
Newsgroups: perl.moose
From: d...@tozt.net (Jesse Luehrs)
Date: Mon, 8 Oct 2012 10:03:24 -0500
Local: Mon, Oct 8 2012 11:03 am
Subject: Re: attribute initialisation and after

But what if the attribute doesn't have a writable accessor? Being able
to set attributes in the constructor that then can't be changed after
creation is a very common pattern. If all constructor parameters had to
go through accessors, this wouldn't be possible.

This is also quite common in non-Moose classes - typically, constructors
will do something along the lines of

  sub new {
      my $class = shift;
      my %params = @_;

      return bless {
          foo => $params{foo},
          bar => $params{bar},
      }, $class;
  }

and what Moose does is not significantly different from this.

> > I can understand why you would have the expectations you have. I can
> > also understand why I have the expectations I have.

> I don't understand why you have the expectations you have. I'm not even
> sure I understand what those expectations are. Is there any
> documentation that explain what expectations are sensible to have for Moose?

> (one thing I've noticed is that the documents start out by giving basic
> explanations of how to construct objects, and then more complicated
> explanations of what can be constructed, without giving any examples at
> all of how to use the objects.)

This is because once you create the objects, they should be usable just
as any other Perl object. If there is a place in the documentation that
you think could be improved, we are always open to documentation patches
- doc patches from new users tend to be very helpful because they still
know which parts are confusing(:

-doy


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Chris Prather  
View profile  
 More options Oct 8 2012, 12:00 pm
Newsgroups: perl.moose
From: ch...@prather.org (Chris Prather)
Date: Mon, 8 Oct 2012 11:52:38 -0400
Local: Mon, Oct 8 2012 11:52 am
Subject: Re: attribute initialisation and after

After I wrote the first response I realized I had never actually
written a class to work the way you expected, though I still do
understand why you would expect that. Even in the pre-moose days
though I'd write constructors like so:

    sub new {
        my $self = shift;
        my $args = @_ > 1 ? { @_ } : $_[0];
        my $class = ref $self || $self;
        return bless $args, $class;
    }

Which doesn't actually behave the way you expect either.

>> 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).

> The call to new is passing in a new value for an attribute.
> The call to the mutator is passing in a new value for an attribute.
> I expect them to treat the new value in the same way in both cases.

Well sure, but what about the case where you have no mutator?

    has foo => ( isa => 'HashRef', traits => ['Hash'], handles => {
... } ); # look ma no mutator

How would you explain the expected behavior then?

How would you explain that state and behavior are isomorphic?

    has value => ( is => 'ro', lazy => 1, default => sub {
long_calculation_in_c() } );

vs

    sub value { long_calculation_in_c() }

I wouldn't expect long_calculation_in_c() to be called if I call
->new(value => $test_value) in the first case ... would you? Is the
default part of the mutator?

What about mutators with side effects?

    use MooseX::Hypothetical::LockableAttributes;
    has value => ( is => 'rw', traits => ['LockOnChange'], lock_timeout => 30 );

The many many variations on mutators is what makes the idea that
attributes and mutators are *different* important. It's the difference
between state (attributes) and behavior (methods ... in this case
accessors / mutators).

>> I can understand why you would have the expectations you have. I can
>> also understand why I have the expectations I have.

> I don't understand why you have the expectations you have. I'm not even
> sure I understand what those expectations are. Is there any
> documentation that explain what expectations are sensible to have for Moose?

Moose::Manual::Unsweetened (
https://metacpan.org/module/Moose::Manual::Unsweetened ) goes a long
way to describing the expected outcome of Moose. Things can always be
better.

> (one thing I've noticed is that the documents start out by giving basic
> explanations of how to construct objects, and then more complicated
> explanations of what can be constructed, without giving any examples at
> all of how to use the objects.)

As Jesse (doy) has said elsewhere in this thread, please if you find
something confusing or you can think of a way to clarify something ...
write a doc patch. The fact that our expectations differ from yours
suggests strongly that we're not the right people to write such a
patch.

>> 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.

> I'm not clear what defaults have to do with it? Nor what would
> constitute unfiring an accessor? Or why you would want to do it?

Not "defaults" in the attribute sense ... defaults in the sense of
"What Moose does without someone altering the behavior by using a
MooseX or other extension". As so why you would want to unfire an
accessor, in the system you described where Class->new( foo => 'bar' )
is exactly equivalent to $o = Class->new(); $o->foo('bar'); any
side-effects that calling the foo() method are unavoidable ... this
makes writing some kinds of accessors more difficult. Moose's
base-line behavior is typically to provide the least intrusive
behavior and let people write out the differences themselves in
extension modules etc.

-Chris


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »