Ovid,

Exploding Tigers. Nice, although you might get some slack from PETA for it. :)

While I agree with all your points (for the most part). I still love my multiple-inheritance. Eiffel provides a handy way to handle some of those name conflicts you speak of, by allowing you to rename methods (among other things). Now Eiffel forces you to adjust your methods to the renamed method. In perl though, this is not nessecary. I submit the following code:

# assume that these 2 methods are # defined in some module and then # exported into your classes's # package namespace. sub redefines ($$$) { no strict 'refs'; no warnings 'redefine'; my ($package, $old_name, $new_name) = @_; my ($caller_package) = caller(); $caller_package->isa($package) || die "Can't rename from a package you do not inherit from"; my $old_method = $package->can($old_name); (defined($old_method)) || die "you cannot rename a method you dont have"; my $current_method; if (exists ${"${caller_package}::"}{$old_name}) { $current_method = \&{"${caller_package}::$old_name"}; } else { $current_method = sub { die "Method no implemented" } } *{"${caller_package}::$old_name"} = sub { my $self = shift; my ($_caller_package) = caller(); return $self->$new_name(@_) if ($package->isa($_caller_package)); # or $self->$current_method(@_); }; *{"${caller_package}::$new_name"} = $old_method; } sub next_method { my ($self, $package, @args) = @_; my ($p, $f, $l, $function) = caller(1); $self->isa($package) || die "Can only dispatch on ancestors of $p"; my @module_path = split /\:\:/, $function; my $caller_function = $module_path[-1]; my $dispatch = $package->can($caller_function); return $self->$dispatch(@args); }
Your Exploding Tiger can then be implemented as such.
use strict; use warnings; package ExplodingTiger; ## import the 2 functions above somehow @ExplodingTiger::ISA = qw(Tiger Bomb); redefines("Tiger", "explode", "spontaneouslyCombust"); sub new { my ($class) = @_; my $exploding_tiger = { bomb_type => "Bomb" }; return bless($exploding_tiger, ref($class) || $class); } sub explode { my ($self, @args) = @_; print "ROAR!!! I'm an exploding Tiger!\n"; $self->next_method($self->{bomb_type}, @args); } 1;

See my scratchpad for a complete runnable example.

Your delegation solution neglected to allow for the original spontaneous combustion behavior to still remain around. It gets redefined in ExplodingTiger::explode. Also, you are faced with the problem that if code from your inherited Tiger class uses the explode method anywhere for a specific purpose it will dispatch to the ExplodingTiger::explode method instead, and the behavior of the Bomb::explode method it delegates too may not be appropriate. The above solution will account for that (see the scratchpad example for the details). It also allows for you to inherit other Bomb methods without needing to delegate.

Another benefit of delegation is that you are relying only on the published implementation. With inheritance, you must comply explicitly with the inherited implementation ...
I am not 100% sure i understand what you are saying here. I assume you are saying that you must deal with the fact a class is inherited, and that is part of the implementation? If that is not what you are saying then disregard the rant that follows, if it is what you are saying, then ...

I believe this is not an issue of inheritance as a concept, but in the implementation of various documentation tools (javadoc, I curse thee!!!).

In Eiffel, there are 2 "views" of a class available in the documentation. A view of the methods implemented by the class directly, and a "flattened" view of all the methods available from the class (all implemented and all inherited).

I believe this takes the OO idea of encapsulation to its next level. In encapsulating inheritance information as well. I mean after all you are supposed to encapsulate/hide the implementation in OOP, and is not inheritance part of a classes implementation?

-stvn

In reply to Re: Re: Object Terminology (and an awful shaggy dog story) by stvn
in thread Object Terminology by stvn

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.