[% setvar title C<@STACK> - a modifyable C %]

This file is part of the Perl 6 Archive

Note: these documents may be out of date. Do not use as reference!

To see what is currently happening visit http://www.perl6.org/

TITLE

@STACK - a modifyable caller()

VERSION

  Maintainer: Simon Cozens <simon@brecon.co.uk>
  Date: 25 Sep 2000
  Mailing List: perl6-language-subs@perl.org
  Number: 299
  Version: 1
  Status: Developing

ABSTRACT

Add a new special variable, @STACK to replace the caller() function. Allow people to modify the call stack in certain, very restricted ways.

DESCRIPTION

Suppose you're writing a debugger; one thing you may want to do is perform some actions when a subroutine ends. Well, if all ops are overridable, no problem; you just override the return op. The only problem here is that you can't write the return operation in Perl.

Don't believe me? This issue also arises at any time you're trying to write something which has the effect of a return in the calilng subroutine. You just can't do it. For instance, suppose you want a sub called abort which displays an error message and ends the calling sub:

    if ($badness) {
        abort("Something yukky happened");
    }

    sub abort {
        warn @_;
        return 0;
    }

Uhoh; that return only finishes abort - it doesn't finish the calling sub. Inlining the sub by means of something like sub abort : inline won't actually help either, unless it's replaced like a macro. (Yuck.)

One way to fix this would be to have the call stack available from Perl space. That's roughly what the caller() function does, and that's there for a good reason. However, if we could get at the call stack via an array, we could solve the problem like this:

    sub abort {
        warn @_;
        pop @STACK;
    }

I would have to stipulate that pop was the only modifying operation permitted on @STACK - pushing to it would be Evil and Bad and Wrong, like the goto from the ninth level of hell.

But what should be in each element of @STACK? If we had each element representing the output of caller(), we could do away with that too. The following equivalences hold between Perl 5 and Perl 6:

    Perl 6     => Perl 5
    $STACK[-1]  = [caller(0)];
    $STACK[-2]  = [caller(1)];
    ...

IMPLEMENTATION

Making the call stack available to Perl is easily done, since we do exactly that in caller(); changing that to a special variable via whatever becomes of the magic system shouldn't be too difficult.

Modifying it is a little more tricky, but can be done with the same magic that goto &thing uses.

REFERENCES

RFC 21: Subroutines: Replace wantarray with a generic want function