Very nice meditation and very interesting technique (I took a look at some of the "guts" of it here as well). However I must say that it seems like a lot of overhead in single inheritance situations.

This is the dreaded "diamond inheritance" problem: if Base provides a compile() method, which Filter and Safe each override to perform additional actions around a call to SUPER::compile, how can we ensure they are all called in sequence?

In my experience, it is not usually just an issue of FilterSafe calling them in the right sequence, but doing what you say Filter and Safe do and performing additional actions around calls to the superclass's compile method. So while many times I would like to be able to just use something like NEXT, I find that I must instead do things like $self->Filter::compile() and $self->Safe::compile() instead. And to be honest this no longer bothers me, and I have now learned to see it as an elegant way to specifically direct method dispatch in the presences of multiple inheritance.

However, your medition got my mind moving and I decided to see if I couldn't create a simple NEXT-ish type module which would dispatch to all the superclasses in the same order as the modules were inherited, and without some of the odd craziness which NEXT seems to require (in the examples all calls go through NEXT:: even in the base classes and single inheritance classes).

package SUPER::DISPATCH; our $AUTOLOAD; sub AUTOLOAD { my ($self, @args) = @_; my $a = $AUTOLOAD; my ($method) = ($a =~ /SUPER\:\:DISPATCH\:\:(.*)/); my $calling_package = caller(0); no strict 'refs'; my @callingISA = @{"${calling_package}::ISA"}; foreach my $superclass (@callingISA) { my $supermethod = $superclass->can($method); $supermethod->($self, @args) if $supermethod; } } package Base; sub new { bless {}, $_[0] } sub compile { my ($self) = @_; print("> compile called in Base by " . (caller())[0] . "\n") } package Filter; use base ('Base'); sub compile { my ($self) = @_; $self->SUPER::compile(); print("> compile called in Filter by " . (caller())[0] . "\n"); } package Safe; use base ('Base'); sub compile { my ($self) = @_; $self->SUPER::compile(); print("> compile called in Safe by " . (caller())[0] . "\n"); } package SafeFilter; use base ('Filter', 'Safe'); sub compile { my ($self) = @_; $self->SUPER::DISPATCH::compile(); print("> compile called in SafeFilter by " . (caller())[0] . "\n") +; } package main; my $sf = SafeFilter->new(); $sf->compile(); __OUTPUT__ > compile called in Base by Filter > compile called in Filter by SUPER::DISPATCH > compile called in Base by Safe > compile called in Safe by SUPER::DISPATCH > compile called in SafeFilter by main

I am not sure if this would solve the specific problem you have though, but it does solve the "diamond inheritance/called in sequence" issue you mention. Anyway, back to work, thanks for the mental jumpstart, very nice meditaion.

-stvn

In reply to Re: Solving the SUPER problem in Mixins with String Eval by stvn
in thread Solving the SUPER problem in Mixins with String Eval by simonm

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.