Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

Re: inheritance turns back and bites

by stvn (Monsignor)
on Mar 01, 2004 at 19:35 UTC ( [id://333025]=note: print w/replies, xml ) Need Help??


in reply to inheritance turns back and bites

Disclaimer
Sorry, but first i have to rant. This is not nessecarily 100% about your code, but about a particular Perl-OO idiom I see often on this site.

Maybe, I'm a prude, but I just don't understand how anyone could think that this idiom:

# sub new { bless \pop, shift } sub new { my $self = pop; bless \$self, shift }

is good OO. It completely externalizes the internals of the object in the worst way by allowing the caller of "new" to essentially create them. It does no form of parameter checking at all, and is lazy in the worst way (creates more problems later on, instead of solves them).

Your code breaks in silently if I do any of these things:

MyNumber->new([ 0 .. 100 ]); MyNumber->new({ test => 1}); MyNumber->new(*STDOUT);
Now of course, these are "unrealistic" examples because your classname and documentation would indicate doing such things were just plain stupid. But, in a larger program (especially with a number of developers) variables may get trampled on, or return values are changed, or any other such issue. If the eventual argument to your constructor is just such a vicitim, your object willingly accepts it without complaint. And when your code suddenly die's (possibly) far away from where the actual bug was created, you may waste hours tracking it down.

Now onto your questions:

  1. what is wrong
  2. the most elegant way to fix it
  3. what can be done to avoid similar errors
Question "a" has already been answered, its because "increment" is using "add" from MyNumber and not from SomeData.

Question "b": My suggestions is to not try and combine string handling and number handling into the same base class. Meaning that SomeData doesn't make alot of sense to me. Especially when you later derive MyNumber from it, and then change the number and type of parameters accepted by "add". This creates a very confusing issue/problem/bug in that MyNumber::add no longer acts the same as SomeData::add and therefore changes the interface.

In a more static language like Java or C# these two methods would be considered different since their method signatures are different. In those langauges your code would work correctly as the call to "add" in "increment" would dispatch correctly to the two argument "add". But alas, this is perl, so I would suggest changing your class design to be more approriate to perls ways and means.

Also, the concept of "increment" is clearly not appropriate to a string. I realize that you specifically call $self->add(number => 1) in the code, but it would seem to me that SomeData is intended to be a string/number handling hybrid base class of some kind, and that implies to me that SomeData should only implement methods appropriate to the both of strings and numbers.

Question "c": see answer to question "b".

-stvn

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://333025]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (7)
As of 2024-03-19 09:51 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found