hossman wrote:

Why make the mutators "set_foo" ... why not just overload "foo" (ie: foo with args does a set, and returns true if-and-only-if the args are valid, without args returns whatever the parameter value(s) should be.

Sorry to come into this late, but I didn't feel the question was answered. There are a couple related reasons not to overload mutators or accessors.

Most of the time, coders are aware whether they intend to call a mutator in "set" or "get" mode. This awareness happens at coding time.

Having separate mutators for "set" and "get" allows code to be explicit about its intentions. Mutators may be prototyped such that accidentally supplying or omitting a parameter is a compile-time error rather than a runtime misbehavior. If prototypes aren't desirable, separate mutators still makes mismatches between design and code more visible.

To illustrate that last point, compare misused overloaded mutators with misused explicit ones.

$thing->foo(); $foo = $thing->foo($bar);

vs.

$thing->get_foo(); $foo = $thing->set_foo($bar);

The latter form of each example is legal code, and only the surrounding context will determine whether they are errors.

An obvious solution is to check the number of parameters given against the mutator's runtime context. The resulting code might look like this.

sub foo { my $self = shift; if (@_) { if (defined wantarray) { croak "can't expect a return value when setting foo"; } # store foo = shift; } else { unless (defined wantarray) { croak "must expect a return value when fetching foo"; } # return foo member here } }

That has its own drawbacks.

"set" mutators cannot be chained. While foo() might return $self in "set" mode, the wantarray() check would make it an error to actually use it.

"set" mutators cannot be allowed to return their members' new values. Even if they did, the wantarray() checks would prohibit code like print $thing->foo($new_value);

It's still a runtime error. Ideally every line of a program should be instrumented before it goes into production. Pragmatically speaking, compile time errors are better at preventing bogus code from being released.

Even if these problems are not an issue for a particular application, every mutator has gained an enormous amount of avoidable runtime overhead.

-- Rocco Caputo - troc@pobox.com - poe.perl.org


In reply to Re: Re: RFC - Parameter Objects by rcaputo
in thread RFC - Parameter Objects by Ovid

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.