Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine

Re^2: Moose: I want builder method to run every time I call an attribute

by boftx (Deacon)
on Sep 26, 2013 at 23:08 UTC ( #1055920=note: print w/replies, xml ) Need Help??

in reply to Re: Moose: I want builder method to run every time I call an attribute
in thread Moose: I want builder method to run every time I call an attribute

I concur with chromatic. That said, if there are some other factors in play that preclude doing this, you might consider using an around statement in conjunction with the attribute reader to handle any pre-processing needed. You might not even need to have an explicit builder in that case.

On time, cheap, compliant with final specs. Pick two.
  • Comment on Re^2: Moose: I want builder method to run every time I call an attribute
  • Download Code

Replies are listed 'Best First'.
Re^3: Moose: I want builder method to run every time I call an attribute (ugh)
by tye (Sage) on Sep 27, 2013 at 01:14 UTC

    Two perfect examples of how Moose encourages bad OO design.

    - tye        

      tye, in all seriousness, would you expand on that (rather broad) statement? I realize this could touch off a "tastes better/less filling" discussion with regard as to what proper OO design is, but I would like to know the basis for your statement. especially since chromatic has a much better claim to knowing what he is talking about than I do in this community. :)

      On time, cheap, compliant with final specs. Pick two.

        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        

        I have these bookmarked/tagged with oop and tye and in proximity to each other
        How Large Does Your Project Have To Be to Justify Using Moose?,
        Re^2: Two simple code style advice questions (tye)
        module w/ object-oriented and functional interfaces: best practices?
        Advice please on variable naming style in modules
        Re: Object Oriented Orientation
        encapsulation violation Re: Programming patterns Programming patterns
        Moose class design for game

        And tye in the cb around the same time( 2011-06-18 06:23:39 UTC )

        the Moose will bite you in the end
        The classic steps of bad OO design are done in the following order: 1) Figure out which classes inherit from which other classes, 2) Figure out the attributes of each class, 3) Starting writing methods.
        ugh. data-type-based validation. If you want C++, you know where to find it. That's another thing Moose promotes that I find problematic.
        So, Moose pretty much forces you to only use attributes via accessors (that it generates). This forces your attributes into public view and leads to classes with lots of accessors. Bad design.
        Never inheritance! Though, you'll want simple delegation sometimes and there isn't a great solution for that yet (I'm working on it)
        It leads to fragile and overly complex design for a ton of reasons.
        The argument 'for' is that it can then be easy to muck with things in several rather unstructured ways. Rather like the argument for 'goto'. You don't have to bother to make the design structure clear. Just slap things however.
        No, I think OO is great. Inheritance sucks big time.
        Roles improve inheritance in some fairly superficial ways but don't fix the bad design aspects much if at all.
        And my disagreement with Moose's take on OO is not anything about 'anal'. It puts way too much stress on accessors, encourages validation only via data types. It adds the worst aspects of C++ and doesn't implement many good, required parts
        I don't mind having a good structure for doing OO. Moose got a lot of things right about that. But the negative still outweighs the good, IMO.
        Every so often I have to go find some good old hackers and ask them if inheritance is good so they can laugh at me and remind me how stupid the old-timers realize it is. This knowledge is not only not shared by enough people, but ...

        I also bookmarked meaning to ask something about coupling controllers, but I don't remember

        I also remember that tye is writing a oop/ood book(let?) , can't wait for 50 shades of tyed oops

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1055920]
[ambrus]: Eily: hmm... do you count your user and your scratchpad as root nodes you posted?
[Eily]: I would have if it had been convenient :P
[hippo]: Those are auto-posted. We just update them.
[LanX]: "you haven't been a monk" ???
[LanX]: oh "yet" .. got it
[Eily]: LanX: sadly I wasn't born a monk
[LanX]: #SoSad #Shame
LanX silently plays Springsteen in the background "♪..♫ ... I'm on fire ..."

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (7)
As of 2017-03-24 14:45 GMT
Find Nodes?
    Voting Booth?
    Should Pluto Get Its Planethood Back?

    Results (304 votes). Check out past polls.