Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling

Re: Moose role BUILD question

by stvn (Monsignor)
on Mar 24, 2011 at 13:20 UTC ( #895246=note: print w/replies, xml ) Need Help??

in reply to Moose role BUILD question

Actually this code has a problem, if your class has a BUILD method in it, then the role method will never get consumed. ikegami's solution will fix it for you, but it bypasses the nice aspects that BUILD and the BUILDALL method that calls it.

Instead I suggest the more common Moose idiom which is to use method-modifiers with roles and BUILD, so your Browser role would look more like:

package Browser; our $VERSION=0.01; use Moose::Role; requires qw(cookieCreate cookieDelete navigation); sub BUILD {} after 'BUILD' => sub { my $self = shift; $self->cookieCreate; };
This will then work with classes which do not have an existing BUILD (by installing the empty one in the role) and ones which have an existing BUILD (local class beats role in composition, but the after modifier will always get applied).


Replies are listed 'Best First'.
Re^2: Moose role BUILD question
by ikegami (Pope) on Mar 24, 2011 at 18:53 UTC
    I agree that your solution is more idiomatic and cleaner, but what features are bypassed by the method I posted?

      The real problem was more in the OPs code. By putting a BUILD method in his role, he would have run into an issue if he tried to compose it into a class which already had a BUILD, because the local class version of a method beats the role version of it. So actually it is not really that your version was bypassing so much as just not using Roles properly. Once a role is composed into a class, it really should be "forgotten" about since all the methods are basically already "copied" into the class.

      Additionally, the BUILD method is never really meant to be called by outside-of-Moose-internals code, it is meant to be called by BUILDALL and in a very specific order so that the object is initialized properly. This is all done within the context of inheritance, which is a Class specific thing. Roles do not inherit, which is why we have to do the weird tricks I showed above to hook into BUILD from a role. So while your solution will force the call to Browser::BUILD and it will happen during the BUILD of the consuming class, it is bypassing all that machinery. Currently, the result is the same, but since you are calling things usually only reserved for internals to call, there is a possibility (although very slim) that this might cause issues down the road.


Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://895246]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (5)
As of 2018-02-24 16:25 GMT
Find Nodes?
    Voting Booth?
    When it is dark outside I am happiest to see ...

    Results (310 votes). Check out past polls.