Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

comment on

( [id://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:

add($duration)
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 :-)

cheers,
Aldo

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

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (2)
As of 2024-04-16 19:51 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found