Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options

Comment on

( #3333=superdoc: print w/replies, xml ) Need Help??
time to clarify things up :-)

I would like to thank everyone that answered to this rather silly post, and took part in a sort of bad joke of mine.

I had prepared a very different kind of posting, talking about inheritance, interfaces and code maintenance, but in the end I decided to try to be thought-provoking and so posed the question as a sort of quiz. and I'm sorry if this caused more harm than good :-).

almost everybody spotted the error in redefining the interface (or the signature, if you prefer to think in terms of it) for a method in a derived class.

the rule I wanted to point out, which in Perl (due to its typeless and prototypeless nature, that we all sometimes love) may easily go overlooked (I, for one, didn't had it so clear in mind before stepping on it):

Don't change the interface of methods you overload from a base class (that is, you can do things differently internally, but both input and output should be consistent with the original method) or inheritance will turn back and bite you.

and that's my exposition of point c. regarding point b (a way to fix this), many (here and in other forums) suggested checking the number, and possibly the nature, of parameters in MyNumber::add, as per broquaint's:

@_ > 2 && return $_[0]->SUPER::add(@_[1..$#_]);
this has the disadvantage that one can still write: $answer->add(string => 'xxx'), and this may very well be what the author of MyNumber wanted to avoid.

one could check the value of the second parameter, and die unless it is number, but this seems rather kludgy.

a slightly less inelegant way to fix this problem could be for example:

sub add { # check if the Big Boss is calling us... if( (caller(1))[3] =~ /^SomeData::/) { # we feel guilty, so let's hide return shift->SUPER::add(@_); } # ...back to our scheduled job my($self, $value) = @_; die "not a number" unless $value =~ /^\d+$/; $$self += $value; }
but still broquaint's hint on Class::Multimethods wins this thread's elegance award.

as a final note, I will also unveil where really I encountered the problem (so that you can finally forget about my broken example :-). I was taking a look at Net::ICal for a project of mine, and I found that Net::ICal::Time, which is intended to be just a wrapper class for Date::ICal, defines a method:

but Date::ICal has an add method, which has this synopsis (as well as others):
add(duration => $duration)
and that's exactly our point a. the code in Net::ICal::Time::add ends with:
return $self->SUPER::add(duration=>$duration);
but as we saw, this is not enough to be safe.

to further underline how sneaky this bug can be, I will also add this: the code in Date::ICal::new, which Net::ICal::Time delegates to, calls offset, which in turns calls add (which is really Net::ICal::Time::add) only when it has to do some adjustment to account for timezones.

and that's all for today. I hope you found all this somewhat entertaining :-)


King of Laziness, Wizard of Impatience, Lord of Hubris

In reply to inheritance turns back and bites (for real this time) by dada
in thread inheritance turns back and bites by dada

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, 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, 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.
  • Log In?

    What's my password?
    Create A New User
    and all is quiet...

    How do I use this? | Other CB clients
    Other Users?
    Others contemplating the Monastery: (5)
    As of 2018-05-26 18:51 GMT
    Find Nodes?
      Voting Booth?