Mr.T has asked for the wisdom of the Perl Monks concerning the following question:

Hello fellow monks:

I have studied the man pages perlboot and perltoot fevorishly, but I still don't understand the concept of inheriting. I don't understand how inheriting really works. I have seen many examples that use inheriting, however, I have no clue how it really works.

I have not really done any C++ and only a little Java, so I am not very used to object oriented programming, consequencly, the same is true for me in Perl. I have read through the tutorials under the OOP section here at the monastary as well, however, I still don't understand what inheriting really is.

How would I use it in a very basic OOP (simple) example in Perl?

Thanks in advance.

Mr.T
print "I pity the $foo !\n";

Replies are listed 'Best First'.
Re: Understanding what Inheriting is.
by VSarkiss (Monsignor) on Aug 13, 2001 at 01:32 UTC

    OK, "how to use it" and "how does it work" are very different questions. I'll leave the second point to monks who understand the internals of Perl better than I, and just try to give you a feel for the motivation behind inheritance.

    Inheritance is a programming construct that's supported directly in object-oriented languages (such as Smalltalk) and can be retrofitted into some others (such as Perl). Basically, it addresses the situation where you've found some code that does almost everything that you need, but not entirely. In that situation, you have some choices:

    • Change your solution to fit the code you found
    • Copy-and-paste the code into your program and modify
    • Use the code you found, but add your functionality to it

    The first technique is usually not available if somebody's paying you to write the code -- although if it's available, it may be the most expedient way of getting what you want done!

    The second usually creates maintenance headaches because it breaks the link to the origignal. For example, suppose the original author finds a bug and publishes a fix. Now the person maintaining your code has to find out about the bug, then figure out whether and how the fix applies to your modified version. Or a spiffy new version comes out and now you have copy and paste all over again. (Many other scenarios are possible, but I just want to give you the flavor.)

    The third option is what inheritance does. It lets you create new code that looks and acts like the old code (as a matter of fact, it calls the old code!), except where you add new stuff.

    For example, say you found a great (Perl module, Java class, C++ library) called SuperCool that does 98% of what you want, but you just need to add a couple of things. With inheritance, what you can do is create a class that inherits from SuperCool called, say, HyperCool. This one has all the methods of SuperCool, and the ones you added, but you don't have to duplicate the code for SuperCools's methods. The languages that support OOP will figure out if a call to a method in HyperCool is actually for code written in SuperCool, and will dispatch to that code with the calling client program being none the wiser. The net result is that you're able to provide SuperCool's functionality, and add to it, in a maintenance-friendly way.

    There is a lot more that can be said about the topic. This is a miniminal overview, but hopefully it'll allow you to understand the more advanced material.

    HTH.

Re: Understanding what Inheriting is.
by lemming (Priest) on Aug 13, 2001 at 00:54 UTC

    I would suggest reading and digesting Object Oriented Perl by Damian Conway. It cleared up a lot for me.

    Review here and buy here

Re: Understanding what Inheriting is.
by toma (Vicar) on Aug 13, 2001 at 06:46 UTC
    Here is a simple example of using inheritance:

    Say you have some stock footage for an action-adventure TV show, and you want to re-use it several times without anyone noticing. This week, we are going to flip a jeep and distract some guards.

    use strict; use ordnance; my $T= new ordnance(); $T->flip_jeep(); sleep 2; $T->firecracker();
    This week's episode uses the ordnance module, which inherits from the stock_footage module.

    Here is ordnance.pm:

    package ordnance; use stock_footage; @ISA=qw(stock_footage); sub new { my $this = shift; my $class = ref($this) || $this; my $self = {}; bless $self, 'ordnance'; } sub flip_jeep { my $this = shift; my $class = ref($this) || $this; print "pull grenade pin\n"; sleep 2; $class->SUPER::flip_jeep(); } sub firecracker { my $this = shift; my $class = ref($this) || $this; print "light fuse\npsssss....\n"; sleep 2; print "Bang! Bang! Bang!\n"; $class->SUPER::distraction(); } 1;
    and here is stock_footage.pm:
    package stock_footage; sub flip_jeep { print "And the jeep flies into the air and flips!\n"; } sub distraction { print "And the guards are momentarily distracted!\n"; }
    So, someone can write this week's show using my ordnance routines, and they won't know that they are actually using stock_footage. Of course, I would write pod documentation for my ordnance routines so that the caller doesn't have to look at the ordnance code to know how to use it.

    I have not written much code that uses inheritance, but I'm sure that other monks can correct me if I have messed up my code. There are many things you can do with inheritance, just as there are many things you can do with a for loop. I would like an even more brief example, if someone can figure one out.

    UPDATE:Fixed problems pointed out by tilly and petdance.

    It should work perfectly the first time! - toma

      Prototypes are ignored on method calls, so your prototypes are doing nothing. You should drop them. (I prefer not using them ever. But that is me.)

      As for short examples, well OO is aimed at making longer code maintainable, not at making short examples. But still in Re (tilly) 8: To sub or not to sub, that is the question? I gave some code that has appropriate method calls inserted and some explanation for how you would use inheritance.

      ++ on the explanation, toma. Quick aside, though:

      "ordinance" means "an authoritative decree or direction." The word you want is "ordnance", which means "military supplies including weapons, ammunition, combat vehicles, and maintenance tools and equipment."

      xoxo,
      Andy
      --
      <megaphone> Throw down the gun and tiara and come out of the float! </megaphone>

      Why do you use SUPER:: in your calls to stock_footage methods of flip_jeep and distraction?

      Since ordinance @ISA = qw(stock_footage); couldn't you use

      $this->flip_jeep()

      instead of
      my $class = ref($this) || $this; $class->SUPER::flip_jeep();

      What am I missing about your example?

        I tried your suggestion and got an infinite loop. I pulled many grenade pins!

        It should work perfectly the first time! - toma

Re: Understanding what Inheriting is.
by clemburg (Curate) on Aug 13, 2001 at 15:05 UTC

    I'd like to follow lemming in suggesting that you should read Object Oriented Perl from Damian Conway. It contains a very good introduction to objects "in general".

    As VSarkiss noted, "what inheriting really is" and "how inheriting really works" might be two questions: what inheritance is, conceptually, vs. how inheritance is implemented in Perl.

    This makes a real difference, as Perl implements inheritance differently than, e.g., C++ or Java.

    Basically, "inheriting" from a class means that you can use operations (methods) and access variables (attributes, properties) that you have not defined in the inheriting class, but which are defined in the class you inherited from or one of its ancestor classes.

    Now, how do you implement this?

    One common implementation method (e.g., C++, Java), sometimes called "implementation inheritance", is to embed an object of the parent class in every object of the inheriting class. When the object of the inheriting class is now asked for an operation or variable that it does not know about, it forwards the request to the embedded parent class object. (This is fun with multiple inheritance, see C++ "virtual base class").

    Another common implementation method (e.g., Perl, Smalltalk), sometimes called "interface inheritance", is to record somewhere information about the relationship between the inheriting class and its parent class(es), and to provide a language mechanism that uses this information to find the missing operations or variables at runtime. That is, when you invoke an operation or access a variable via an object, and the object does not know about it, some mechanism will kick in and search the parent classes for the operation or variable until it finds it.

    In Perl, you inherit only methods. Camel III, p. 321 says: "This is how Perl implements inheritance: each element of a given package's @ISA holds the name of another package, which is searched when methods are missing."

    Christian Lemburg
    Brainbench MVP for Perl
    http://www.brainbench.com

Re: Understanding what Inheriting is.
by Boots111 (Hermit) on Aug 13, 2001 at 20:34 UTC
    I suppose what I am about to suggest is anathema, but I shall suggest to you a series of books that are not about Perl.

    Bruce Eckel writes a series of books (Thinking in C++ and Thinking in Java) that do a very good job of explaining what object oriented programming is, what it does, how it works, and the situations in which it is appropriate. Because not everything needs to be an object <cough>java<\cough>. While the information he provides will not tell you the specifics on how to do this in Perl. It will help your overall understanding of OOP and that will make you a better programmer in Perl too.

    Moreover, both of these books are available for free in electronic format. Doesn't get much better than that.

    Matt