Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine

Answer: Why is it said that Perl does not implement true object orientation?

by ariels (Curate)
on Aug 20, 2001 at 16:42 UTC ( #106203=categorized answer: print w/replies, xml ) Need Help??

Q&A > object-oriented programming > Why is it said that Perl does not implement true object orientation? - Answer contributed by ariels

As seen above, it all depends on what you want in your OO programming language. Here's another feature that Perl is missing: proper inheritance of data members (not just functions!).

Perl has no safe way of storing instance variables of your objects. The canonical way to do this is to make your objects blessed hash refs, keeping the instance variables in hash entries. I'll analyse that case, because it's the most common, and because other methods suffer from exactly the same problem.

But what happens when you try to inherit? You have two classes using keys in the same hash. The inheriting class might not know which keys are used in the base class. And if both classes try to use the same key to refer to instance variables they consider their own, trouble is certain.

Say you have a Crypto class, which does some cryptographics. Internally, Crypto reads from a file. So it stores a filehandle in the _fh key of the object.

Now I come along and write the LoggedCrypto class, which inherits from Crypto but also keeps a record of something. I'm writing to a file, so I guess it will be a good idea to store the log file's filehandle in the object's _fh key. Remember that keys beginning with an underscore are meant to be private, so it's "good" that I don't know this key is already in use!

Predictably, havoc ensues. Contrast this with (for instance) C++, where private instance variables just aren't visible from outside their class!

Multiple inheritance makes everything much worse. Now I have several completely independent classes, and I try to use them together by saying

package Derived; use strict; use BaseA; use BaseB; use BaseC; use var qw/@ISA/; @ISA = qw/BaseA BaseB BaseC/; sub new { # arrange for proper construction... # ... }
(Writing new in this case is also non-trivial, and will in general require that the Base.* classes have special auxiliary methods for construction.)

BaseA, BaseB and BaseC all expect (and deserve!) that their instance variables be kept separate. They're not.

How can we get around this? One way is to prefix our keys with our package name. Then we have keys _Crypto_fh and _LoggedCrypto_fh, and no clashes. But that's cumbersome and a maintenance nightmare (imagine renaming LoggedCrypto to Crypto::Logged). Another problem is that you cannot use a (think "protected") instance variable without knowing the exact point on the inheritance hierarchy which "owns" it. That makes changing the hierarchy (e.g. splitting the base class into 2 inheriting classes) nearly impossible.

This problem is real.

  • Comment on Answer: Why is it said that Perl does not implement true object orientation?
  • Download Code
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 cooling their heels in the Monastery: (5)
As of 2018-03-17 23:22 GMT
Find Nodes?
    Voting Booth?
    When I think of a mole I think of:

    Results (227 votes). Check out past polls.