Damian Conway <[EMAIL PROTECTED]> writes:

> Richard Proctor asked:
>
>  > If one has a simple sub such as factorial:
>  >
>  > sub factorial(int $a) {...}
>  >
>  > then one subsequently declares the multi form of factorial to pick up the
>  > non-integer form:
>  >
>  > multi factorial(num $a) {...}
>  >
>  > Does this promote the original declaration of factorial to a multi?
>  > if not what happens?
>
> What happens is that the subroutine hides the multimethod
> (thoroughout the subroutine's package).
>
> We didn't include it in A6 but our current notions (i.e. this week ;-)
> about interactions between subs, methods, and multimethods are
> something like this:
>
>                               Dispatched to first existing
>      Call                     and visible of...
>      ====================     ============================
>
>      foo($x, $y);             1. C<sub DISPATCH>
>                               2. C<multi DISPATCH>
>                               3. C<sub foo>
>                               4. C<sub AUTOLOAD>
>                               5. C<multi foo>
>                               6. C<multi AUTOLOAD>
>
>
>      Invocant.foo($x, $y)     1. C<method Invocant::DISPATCH> or inherited
>                               2. C<multi DISPATCH>
>                               3. C<method Invocant::foo> or inherited
>                               4. C<method Invocant::AUTOLOAD> or inherited
>                               5. C<multi foo>
>                               6. C<multi AUTOLOAD>

This looks like a classic Chain of Responsibility pattern. I wonder,
would it be possible to expose the dispatch system as an object
(chain) which could be modified by the courageous programmer so that
one could, for instance, set up a different dispatcher for the rest of
a lexical scope which dispatched to multimethods before subs/methods? 

I know you could override it by implementing your own DISPATCH sub,
but an OO interface does have a certain appeal to it. Hell, one could
probably implement a suitable DISPATCH sub that would look for a
$*DISPATCHER and dispatch via that if it existed or just do a NEXT
call if it didn't. Something like this might do the trick:

    sub DISPATCH { 
        if (defined $*DISPATCH) {
            $*DISPATCHER.dispatch(@_);
        }
        else {
            NEXT(@_);
        }
    }

So, even if there isn't a 'core' way of manipulating the current
dispatcher it's possible to write a module that would make it look
like you could.

Sometimes I scare myself.

-- 
Piers

Reply via email to