Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked

Re: Mutator chaining considered harmful

by eric256 (Parson)
on Dec 28, 2004 at 23:23 UTC ( #417878=note: print w/replies, xml ) Need Help??

in reply to Mutator chaining considered harmful

Perhaps is my past with VB but

my $label_formatting = $window->title( 'foo' ) ->child->border( 20 ) ->child->font_style;

Makes a huge amount of sense. You want to set the windows title, grab its kid, set its border, grab the kids kid, and get its font_style. While I wouldn't recommend grouping the getter with all the rest, I think its a fine style, if its what is needed. Sometimes you don't want tons of variables when a simple call like that will work. Just as long as the documentation makes it obvious what the methods do I don't see why anyone should complain. To each his own style, if you don't like it, don't use it. If you are going to recommend agianst it, I for one would like you to back it up with more than this.

Eric Hodges

Replies are listed 'Best First'.
Re^2: Mutator chaining considered harmful
by diotalevi (Canon) on Dec 29, 2004 at 08:15 UTC
    What kind of kid would the 'foo' title have? Would a window even have multiple titles? That code reads like "Get the child of the title currently named 'foo' from $window where the border is already 20. From there get font style of that object's child." There isn't anything in that chain that is a mutator if you read it using perl5 or VB eyes.

      I don't disagree that it can be misread. Anything can be misread. If you are used to mutators that return the object they mutate, then there is nothing confusing about it. If you are not used to that style then it is confusing. That is no different than other styles. With any style different from your own you will have to learn it. Saying that you don't read it correctly because you don't use that style doesn't mean the style is bad.

      There are however some reasons that style is bad. Mostly it makes it difficult to catch errors if those methods fail. A simple although not elegant solution to that would be to store an error code or message in the object when an error occurs. I'm not recommending that or this style. I just think a post saying this style is bad should include more critism than "I don't like it." and "it's hard for me to read" (not exact quotes, just the feeling i get.)

      If that is not how I should read your argument than I would appreciate a better explanation of why its bad. If not for myself then for others who read this node. Like I said, I don't think this is the best style all around but there are cases where it is usefull.

      Eric Hodges

        Mostly it makes it difficult to catch errors if those methods fail.

        But not any more difficult that catching an error in *any* chaining call. The OP had no problem with:
        my $label_formatting = $button->child->font_style;
        but if there's an error in the child method, it'll be as hard to catch as in:

        And if your methods just throw exceptions on errors, you can just wrap it all in an eval:

        eval {$window->title('foo')->border(20)}; if ($@) { something...}
        If that isn't good enough for you, because you need fine grained control on catching errors, you can always write:
        eval {$window->title('foo')}; if ($@) {....} else {eval {$window->border(20)} if ($@) {....}}
        The point is that mutators returning $self allow for either style. Chaining for those who want it, and fine control for those who want that.

        Returning the argument passed in is IMO not very useful. The OP mentioned "that's how = does it - it allows you to write $foo = $bar = $baz;. That's true, but the OO equivalent would be:

        which, IMO, gets unwieldy very quickly and isn't very readable either. I also have seldomly any use for that.

        Your entire post is predicated on a simple straw man argument. You claim that Aristotle is against method chaining because he isn't "used to" it. Frankly, I think that's condescending and silly, but it's also wrong. The argument isn't that it's hard to "get used to," but that even if you are intimately familiar with it, it's hard to understand code that uses it. Take this code example:


        Versus this one:

        my $bar = $foo->bar(2); $bar->baz(3); $bar->qux;

        The first requires a lot more effort to decipher than the 2nd. If you're not familiar with the methods and their return values in the 1st snippet, you'd have to look them up in the documentation. Even if you knew the method return values off the top of your head, you'd have to trace the chain carefully to make sure you understand what's going on.

        In the 2nd, if you didn't know the return values, you could take a reasonable guess, and probably be right. And if you did know the return values, then it's obvious what's going on without any thought required at all. This is called self documenting code, and it's generally something we strive for.

Log In?

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

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (5)
As of 2017-02-21 01:10 GMT
Find Nodes?
    Voting Booth?
    Before electricity was invented, what was the Electric Eel called?

    Results (304 votes). Check out past polls.