I have a need to dynamicly build a stack of handlers, which allows one of a higher order to overload the functionality of its parents. ISA and bless() are one solution, but was wondering if

a) is using ISA within a eval exceptable, as i've never seen a similar construction.
b) anybody had a cleaner way todo the following.


Example output:
Object1->Constructor Object2->Constructor Object2->Doit Object1->Doit #!/usr/bin/perl use strict; use warnings; package Interface; our (@IfStack) = (); # Toolset handle stack sub Push { push (@IfStack, @_); # push onto stack } sub Factory { sub Stacker { # Recursively build the object stack # Begin # Inherit base object. # If end of stack, # Spawn the created object (base object) # Else # Recursive into parent. # Relate us with our child. # Call constructor. # End #.. my ($stack, $package) = @_; # current__PACKAGE__ my ($base, $self); if ( scalar (@$stack) ) { # inherit 'base' $base = pop (@$stack); eval "@"."$package"."::ISA=\"$base\""; } if ( scalar (@$stack) == 0 ) { # base class .. spawn $self = eval( "$package->Spawn()" ); } else { # unroll next object $self = Stacker ($stack, $base); $self = bless ($self, $package); } $self->Constructor(); return ($self); } my (@stack) = @IfStack; # clone stack my ($self); die "ERROR: Interface -- object stack empty.\n" if ( ! scalar (@stack) ); $self = Stacker( \@stack, pop(@stack) ) || die "ERROR: cannot build stack.\n"; return $self; } package Interface::Base; Interface::Push( "Interface::Base" ); # push onto stack sub Spawn { my ($obclass) = shift; my ($class) = ref($obclass) || $obclass; my ($self) = {}; return bless($self, $class); } ############################################### # Object1 #.. package MyObject1; sub Constructor { print "Object1->Constructor\n"; } sub Doit { my ($self) = shift; print "Object1->Doit\n"; $self->SUPER::Doit() # chain if ($self->can("SUPER::Doit")); } ############################################### # Object2 #.. package MyObject2; sub Constructor { print "Object2->Constructor\n"; } sub Doit { my ($self) = shift; print "Object2->Doit\n"; $self->SUPER::Doit() # chain if ($self->can("SUPER::Doit")); } ############################################### # TEST MAIN #. package main; my ($ts); print "Main\n"; Interface::Push( "MyObject1" ); # push onto stack Interface::Push( "MyObject2" ); # push onto stack $ts = Interface::Factory(); # create object $ts->Doit(); # call 1;

In reply to Dynamic inheritance by ayoung

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.