nysus has asked for the wisdom of the Perl Monks concerning the following question:

As I use Moose more, I've found it is easy to use some of its mechanisms in ways they probably were not intended to be used and that this can lead to confusing code. One of the things I've been doing is to use the BUILD method to set object attributes. For example, I've got this:

package 'Blah'; use Moose; has attributes => ( isa => 'HashRef' ); has attr1 => ( snip ); has attr2 => ( snip ); has content => (isa => 'HTML::Element'); sub BUILD { my $s = shift; # add attributes to object and/or HTML::ELEMENT in content attribute foreach my $attrib (keys %{$s->attribs}) { # set attributes of an object if it exists if ($s->can($attrib)) { $s->$attrib($s->attribs->{$attrib}); } # set attributes of #HTML::ELEMENT } else { $s->content->attr($attrib, $s->attribs->{$attrib}); } } }

In one way this is convenient as I can just smash all the attributes into one hash and let the class figure out how to process it. I'm now rethinking this, however. I'm wondering what others think. Thanks!

$PM = "Perl Monk's";
$MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate Priest";
$nysus = $PM . ' ' . $MCF;
Click here if you love Perl Monks

Replies are listed 'Best First'.
Re: Is setting attributes with BUILD in Moose a bad idea?
by kcott (Archbishop) on Nov 30, 2017 at 01:36 UTC

    G'day nysus,

    I don't see anything intrinsically wrong with what your doing. In fact, the BUILD section of Moose::Manual::Construction shows a similar example.

    As this was intended to be a general question, I'll just point out BUILDARGS (which is in the same documentation page). In some cases, that may be a better option.

    One of the main differences between the two of those is that BUILDARGS occurs before object creation, while BUILD occurs after. That's typically the main criterion I use when choosing which to use. By the way, you're not restricted to using one or the other: I've certainly used both at various times.

    — Ken

      Yeah, after posting this question, I boned up on Moose construction. One important thing I learned is that Moose will just throw out arguments to the object that aren't used; I had always assumed that would throw an error. So what I ended up doing is using a combination of BUILDARGS and BUILD to process the arguments passed to the constructor before setting the attribs attribute and was able to just get rid of the attrIbs attribute. I think it has made my code a little less inscrutable.

      Thanks for your input.

      $PM = "Perl Monk's";
      $MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate Priest";
      $nysus = $PM . ' ' . $MCF;
      Click here if you love Perl Monks

        > Moose will just throw out arguments to the object that aren't used

        Raison d'être of MooseX::StrictConstructor.

        ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,

        Yeah, after posting this question, I boned up on Moose construction. One important thing I learned is that Moose will just throw out arguments to the object that aren't used; I had always assumed that would throw an error. So what I ended up doing is using a combination of BUILDARGS and BUILD to process the arguments passed to the constructor before setting the attribs attribute and was able to just get rid of the attrIbs attribute. I think it has made my code a little less inscrutable.

        That sounds so bizzare when you say it out loud, is Moose really that impenetrable?

Re: Is setting attributes with BUILD in Moose a bad idea?
by Anonymous Monk on Nov 30, 2017 at 16:32 UTC
    In this and other languages I habitually define an init() method which serves to finish-initializing or to reset an object, returning the object so that the method-call can be chained with others. It is a pragmatic habit to get into . . .