Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??

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":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (4)
As of 2024-03-28 20:46 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found