in reply to Re^2: Understanding 'Multiple Inheritance'
in thread Understanding 'Multiple Inheritance'

Your problem is that connect_to_imaphost is returning the new imap object but maintains no connection between that and the object that you created. They know nothing about each other.

About inheritance, the problem with inheritance is that it is "action at a distance". The behaviour of your code depends on code somewhere over there which you're not looking at right now. Tracking down cause and effect therefore becomes more tricky, and you've opened up the possibility of negative interactions between the functions that you write and the ones that the parent class depends on. That is, you've introduced tight coupling between two pieces of code that are maintained separately.

The strength of inheritance is, of course, that you can avoid writing the same code multiple times in multiple places.

Whether the advantages of inheritance outweigh the disadvantages is situation dependent, and sometimes a matter of opinion. But it is a matter of fact that many people have managed to dig themselves into deep holes using inheritance when it wasn't really appropriate.

By contrast encapsulation and information hiding has much more clear-cut benefits and more minor risks.

I'd suggest reading Code Complete 2 for more detail on this theme. (The first edition didn't cover OO, but did explain enough about encapsulation and information hiding to make it clear what the advantages are.)

  • Comment on Re^3: Understanding 'Multiple Inheritance'

Replies are listed 'Best First'.
Re^4: Understanding 'Multiple Inheritance'
by punkish (Priest) on Mar 08, 2005 at 02:04 UTC
    Thank you tilly. Not only have you helped me understand the problem of "tight coupling" vs. inheritance, you have set me on the right path by pointing out the pitfalls in my current path. I will try another tact with my code... encapsulation and information hiding would be worthy causes to pursue, I don't even know how I can do that when multiple classes are involved without resorting to multiple inheritance.

    In any case, this has been an instructive thread, if I may say so myself.

    --
    when small people start casting long shadows, it is time to go to bed

      I think you're viewing inheritance as the solution without fully understanding just what the implications are. (which is what your original post hinted at). I'll try to explain it simply:

      When you inherit, you make the other module's methods available to whomever might be using your module. When you multiply inherit, you make all methods from all inherited modules available, which may cause interaction problems.

      Typically, when you're looking at when you use inheritance, you look for is-a relationships, rather than has-a relationships. In your particular case, it looks to me as if the IMAP::Client relationship is shaky. (if you want to it almost identically to an IMAP::Client, then it's an is-a relationship. If you want the user of your program to not deal with the IMAP::Client directly, then it's a has-a relationship. It look as if the relation with Config::Simple is definately has-a. Here is the basic logic to deal with the has-a relationships:

      package MyPackage; use strict; use IMAP::Client; use Config::Simple; use Carp; sub new { my $class = shift; return bless {}, ref($class) || $class; } sub load_config { my $self = shift; $self->{'config'} = Config::Simple->new(@_); return $self->{'config'}; } sub connect_to_imaphost { my $self = shift; my $config = $self->{'config'} or croak "ERROR : Connect to imaphost without loading config"; $self->{'imap'} = Mail::IMAPClient->new( Server => $config->{'IMAP_HOST'}, User => $config->{'EM_UNAME'}, .... ); return $self->{'imap'}; } # accessor functions sub imap { return shift->{'imap'}; } sub config { return shift->{'config'}; }

      Now, when you want to use your module, you can do something like:

      use MyPackage; my $pkg = MyPackage->new(); $pkg->load_config('my.conf'); $pkg->connect_to_imaphost();

      And should you need to access the underlying objects:

      my $msg_count = $pkg->imap()->message_count( ... );

      (You don't want to store the return from $pkg->imap() for long term storage, in case the system has to disconnect/reconnect, or something else that change the IMAP::Client object that is associated with your MyPackage object.)

Re^4: Understanding 'Multiple Inheritance'
by Anonymous Monk on Mar 08, 2005 at 13:53 UTC
    Whether the advantages of inheritance outweigh the disadvantages is situation dependent, and sometimes a matter of opinion. But it is a matter of fact that many people have managed to dig themselves into deep holes using inheritance when it wasn't really appropriate.

    By contrast encapsulation and information hiding has much more clear-cut benefits and more minor risks.

    Indeed. And IMO, having proper encapsulation and information hiding is a necessary requirement to be able to do inheritance well.