![]() |
|
Clear questions and runnable code get the best and fastest answer |
|
PerlMonks |
It's a dog, but what kind? (polymorphism , in Perl OO)by blue_cowdawg (Monsignor) |
on Mar 23, 2004 at 19:22 UTC ( #339131=perltutorial: print w/replies, xml ) | Need Help?? |
My Inspiration for this tutorialThe other day a former student of mine posed a programming problem in Perl to me via email. His problem was he needed to write code to handle some data where there were a lot of the same functions were in common for the multiple data types but some of the underlying behaviors were different. He showed me some code and lo and behold in the year since I had him in my class as a student he had taught himself a modicum of Object Oriented Perl technique from the Damien Conway's book on the subject. What am I talking about? Well gentle reader, let me use the following example. Dog ----------> Cattle Dog +-----> Samoyed +-----> Cocker SpanielThe Cocker Spaniel, Cattle Dog and Samoyed are all of type "Dog" and yet they each have different traits and some of the same traits at the same time. For a list of attributes that they have in common (a shortened list here for clarity) are as follows:
Show me the code!Patience gentle reader! One way I could handle this is to create a base class such that: Then I would create a subclass for each breed of dog: and then to instantiate my class in a calling environment I would do the following:
Teaching an old dog new tricksI think there is a better way. What if I could make the base class dog smarter and have it instantiate the subclasses for me? Here is my smarter dog:
OK... so what is going on here? Well now when we want to instantiate a breed we do the following: and what is going on internally in the dog base object is is going to attempt to use a Perl module called "dog::cocker" within the eval statement. If the module does not exist we'll catch the error and the instantiation will fail. So what?Where this comes in handy is where we want to add a new subclass. You create the new module as before: So now we can instantiate a Samoyed similarly.
Let's kick it up a notch! I'm going to add to the base class some default attribute values. The associative array %def_attrs contains attributes that our derived objects can over-ride. In our steps where $self gets initialized we test to make sure the derived object has not yet defined the attribute and we set it if it hasn't. Example of an override:
putting it all togetherThe base module in its entirety (sort of!): and a simple test script: Which when run yields:
Closing thoughtsThis is just the tip of the iceburg. There are many ways you can make use of this techique with many real world applications. For instance: you are going to fork off several sets of child processes with common environmental variables that need to be set and common command line parameters plus a few unique ones. Write a base object with the common values and parameters, have the derived objects override parameters or add new ones as needed and have common "execute" method in the base object to tie it all together. UPDATE:Added "wag_tail" method to the base object and overrode it in two cases.
Back to
Tutorials
|
|