This thread has provoked much thought my part and I would like to hear other monks' opinions

package Person; sub init { ... $self->set_title($title) ->set_first_name($first) ->set_last_name($last); ... }
Here you don't really care which setter blew up, the means to repair the damage lies further up the call stack where the caller of $person->init() is prepared to deal with Person errors. It is perfectly reasonable to chain methods.

On the otherhand

sub mail_customers { foreach my $customer (@customers) { ... my $mail_address = $customer->get_address->as_string; ... } }
is more problematic. Can you be certain that every customer has a valid address object? What about the customers with the special nil address object that stringifies as "Whereabouts unknown"? Is the caller of mail_customers prepared to handle address exceptions? Should mail_customer handle them so it can process the valid customers and then how does the caller find out about the invalid ones?

OK you have validated the input and know that can't happen. What about when mail_customers is extended to keep stats?

$stats{ $customer->address->postcode }++; # zip codes
Does the Solomon Islands have postcodes? I don't know and I suspect that most won't. The problem arises because of the distance between validation of data and its use.

Perhaps mail_customers should only process one customer at a time (and be renamed to mail_customer) and have the loop outside

foreach my $customer(@customers) { next if ! valid_mail_recipient($customer); eval { mail_customer($customer); }; if ($@) { ... } }
but then the loop goes around every call to mail_customer instead of being factored out to mail_customers, however we put the validation of the data closer to where it is used. Maybe that eval block can go. Swings and roundabouts;

My conclusion is that chained methods on the same object for related purposes is a valid idiom which make code easier to understand. Chaining methods on different objects or unrelated methods on the same object, e.g. $reactor->check_pressure->raise_rods, can be dangerous and need to be used with caution. Chaining ten levels is probably ridiculous but with a good example I could be persuaded it is OK in that particular circumstance.


In reply to Re: Unlimited chaining (is there a way to detect this?) by hipowls
in thread Unlimited chaining (is there a way to detect this?) by Burak

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.