chromatic's suggestion was the example of good OO design.

I've talked about this to significant lengths. But I'll let those interested do the searching (it isn't hard) if they want more than the below rehash.

The original question was an example of how Moose's emphasis on object attributes (with the emphasis on method generation, constructor generation, emphasis away from non-accessor use of attributes from within methods, etc.) just further encourages a problematic focus on class design as "select what attributes you want to store in your objects and which of those you want to have accessors for vs. which you just want transparently exposed via constructor arguments".

IME, good OO design comes from first deciding on the methods you want your class to provide and only after that deciding on the attributes that you want to use in order to implement those methods and keeping the attributes as internal aspects of the design that are not directly exposed in the interface. But it took years for me to recognize the pattern of class designs eventually going further and further wrong and distilling out that this was an important common element of many of these problematic designs.

Objects as "bags of attributes" encourages designs that end up leaking/forcing object behavior into the code that uses the objects like this trivial example:

$obj->log() if $obj->should_log();

The original question shows a person so focused on "what accessors to what attributes should I design into my class?" that they didn't even recognize when they had a simple use-case for a simple, vanilla method (the very thing that should be the focus of the design). So they had to conceive of that as "an accessor but that invokes a builder".

Of course, people often deride "blame the tool". It isn't like Moose forces you to design classes badly. But I couldn't resist when I saw somebody who didn't even recognize the need for "just a method".

The second bad example is using "around" code. Not wanting to misquote, I found a prior summary I wrote that I think sums it up nicely so I'll just repeat it, slightly modified:

So you end up defining a "data type" for that attribute and/or you declare a 'before' or 'after' wrapper around the method.

This leads to: "Your logic for a single class will be split apart into tons of tiny pieces where the order and interactions will become almost impossible to see, predict, adjust, and debug. But your code will look pretty. Just don't try to understand it on any sort of deep level (such as when you need to fix something)."

To which stvn, Moose's creator, noted: "Nothing about Moose forces you into doing something as idiotic as you describe."

I prefer to not write idiotic code. I prefer to not come close to writing idiotic code. So I won't be using even one "around" method. The idea of an "around method" just doesn't even make sense in my classes. You can see the code. If you need to add code, you add it where it needs to go and the flow is obvious. And if you later realize that the order of things matters and is wrong, then you fix that by moving lines of code up or down within a subroutine.

- tye        


In reply to Re^5: Moose: I want builder method to run every time I call an attribute (rehash) by tye
in thread Moose: I want builder method to run every time I call an attribute by italdesign

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.