Provided by: libaspect-perl_1.04-1_all bug


       Aspect::Library::Wormhole - A wormhole between call frames


         package A;
         sub new { bless {}, shift }
         sub a { B->new->b }

         package B;
         sub new { bless {}, shift }
         sub b { C->new->c }

         package C;
         sub new { bless {}, shift }
         sub c { ref pop }

         package main;

         print ref A->new->a; # without aspect, prints C

         use Aspect::Library::Wormhole;
         aspect Wormhole => 'A::a', 'C::c';
         print ref A->new->a; # with aspect, prints A


       A reusable aspect for passing objects down a call flow, without adding extra arguments to
       the frames between the source and the target. It is a tool for acquiring implicit context.

       Suppose "A::a()" calls "B::b()" calls "C::c()"... until "Z::z()".

       All is well, until one day you get a requirement with a crosscutting implication- "Z::Z()"
       requires one extra argument. It requires an instance of the class "A". The very same
       instance on which the method "a()" was called, high up the call chain of "Z::z()".

       Without this aspect you can either add a global $Current_A (very problematic), or make
       "A::a()" send "B::b()" its $self, make "B::b()" pass it on to "C::c()", and so on until
       "Z::z()". You are forced to add many arguments to many methods.

       Show me a developer who has never encountered this situation: you need to add an argument
       to a long call flow, just because someone at the bottom needs it, yet only someone on the
       top has it. The monkey code required on each call frame in the call flow, for each
       argument that each target requires, is suffering from EEK- Extraneous Embedded Knowledge

       The code for the frames between the two ends of the wormhole, knows more about the world
       than it should. This extraneous knowledge is embedded in each method on the call flow, and
       there is no easy way to remove it.

       This aspect removes the EEK by allowing you to setup a wormhole between the source and
       target frames in the call flow. The only effect the wormhole has on the call flow, is that
       the target gets called with one extra argument: the calling source object. Thus the target
       acquires implicit context.

       So this wormhole:

         aspect Wormhole => 'A::a', 'Z::z';

       Means: before the method "Z::z()" is called, if "A::a()" exists in the call flow, then
       append one argument to the argument list of "Z::z()". The argument appended is the calling
       "A" object.

       No method in the call flow is required to pass the source object, but "Z::z()" will still
       receive it.

         +--------+                                       +--------+
         | source |    +--------+    +--------+           | target |
         +--------+--> | B::b() |--> | C::c() |--> ...--> +--------+
         | A::a() |    +--------+    +--------+           | Z::z() |
         +--------+                                       +--------+
             .                                                ,
             |                                               /|\
             |                                              / | \
             |                                                |
             +------------- The Bajoran Wormhole -------------+


       The aspect constructor takes two pointcut specs, a source and a target.  The spec can be a
       string (full sub name), a regex (sub will match if rexep matches), or a coderef (called
       with sub name, will match if returns true).

       For example, this will append a calling "Printer" to any call to a sub defined on "Page",
       if it is in the call flow of "Printer::print":

         aspect Wormhole => 'Printer::Print', qr/^Page::/;


       Adam Kennedy <>

       Marcel Gruenauer <>

       Ran Eilam <>


       Copyright 2001 by Marcel Gruenauer

       Some parts copyright 2009 - 2013 Adam Kennedy.

       This library is free software; you can redistribute it and/or modify it under the same
       terms as Perl itself.