Blame README

Packit cde0b4
NAME
Packit cde0b4
    Sub::Uplevel - apparently run a function in a higher stack frame
Packit cde0b4
Packit cde0b4
VERSION
Packit cde0b4
    version 0.2800
Packit cde0b4
Packit cde0b4
SYNOPSIS
Packit cde0b4
      use Sub::Uplevel;
Packit cde0b4
Packit cde0b4
      sub foo {
Packit cde0b4
          print join " - ", caller;
Packit cde0b4
      }
Packit cde0b4
Packit cde0b4
      sub bar {
Packit cde0b4
          uplevel 1, \&foo;
Packit cde0b4
      }
Packit cde0b4
Packit cde0b4
      #line 11
Packit cde0b4
      bar();    # main - foo.plx - 11
Packit cde0b4
Packit cde0b4
DESCRIPTION
Packit cde0b4
    Like Tcl's uplevel() function, but not quite so dangerous. The idea is
Packit cde0b4
    just to fool caller(). All the really naughty bits of Tcl's uplevel()
Packit cde0b4
    are avoided.
Packit cde0b4
Packit cde0b4
    THIS IS NOT THE SORT OF THING YOU WANT TO DO EVERYDAY
Packit cde0b4
Packit cde0b4
    uplevel
Packit cde0b4
          uplevel $num_frames, \&func, @args;
Packit cde0b4
Packit cde0b4
        Makes the given function think it's being executed $num_frames
Packit cde0b4
        higher than the current stack level. So when they use
Packit cde0b4
        caller($frames) it will actually give caller($frames + $num_frames)
Packit cde0b4
        for them.
Packit cde0b4
Packit cde0b4
        "uplevel(1, \&some_func, @_)" is effectively "goto &some_func" but
Packit cde0b4
        you don't immediately exit the current subroutine. So while you
Packit cde0b4
        can't do this:
Packit cde0b4
Packit cde0b4
            sub wrapper {
Packit cde0b4
                print "Before\n";
Packit cde0b4
                goto &some_func;
Packit cde0b4
                print "After\n";
Packit cde0b4
            }
Packit cde0b4
Packit cde0b4
        you can do this:
Packit cde0b4
Packit cde0b4
            sub wrapper {
Packit cde0b4
                print "Before\n";
Packit cde0b4
                my @out = uplevel 1, &some_func;
Packit cde0b4
                print "After\n";
Packit cde0b4
                return @out;
Packit cde0b4
            }
Packit cde0b4
Packit cde0b4
        "uplevel" has the ability to issue a warning if $num_frames is more
Packit cde0b4
        than the current call stack depth, although this warning is disabled
Packit cde0b4
        and compiled out by default as the check is relatively expensive.
Packit cde0b4
Packit cde0b4
        To enable the check for debugging or testing, you should set the
Packit cde0b4
        global $Sub::Uplevel::CHECK_FRAMES to true before loading
Packit cde0b4
        Sub::Uplevel for the first time as follows:
Packit cde0b4
Packit cde0b4
            #!/usr/bin/perl
Packit cde0b4
    
Packit cde0b4
            BEGIN {
Packit cde0b4
                $Sub::Uplevel::CHECK_FRAMES = 1;
Packit cde0b4
            }
Packit cde0b4
            use Sub::Uplevel;
Packit cde0b4
Packit cde0b4
        Setting or changing the global after the module has been loaded will
Packit cde0b4
        have no effect.
Packit cde0b4
Packit cde0b4
EXAMPLE
Packit cde0b4
    The main reason I wrote this module is so I could write wrappers around
Packit cde0b4
    functions and they wouldn't be aware they've been wrapped.
Packit cde0b4
Packit cde0b4
        use Sub::Uplevel;
Packit cde0b4
Packit cde0b4
        my $original_foo = \&foo;
Packit cde0b4
Packit cde0b4
        *foo = sub {
Packit cde0b4
            my @output = uplevel 1, $original_foo;
Packit cde0b4
            print "foo() returned:  @output";
Packit cde0b4
            return @output;
Packit cde0b4
        };
Packit cde0b4
Packit cde0b4
    If this code frightens you you should not use this module.
Packit cde0b4
Packit cde0b4
BUGS and CAVEATS
Packit cde0b4
    Well, the bad news is uplevel() is about 5 times slower than a normal
Packit cde0b4
    function call. XS implementation anyone? It also slows down every
Packit cde0b4
    invocation of caller(), regardless of whether uplevel() is in effect.
Packit cde0b4
Packit cde0b4
    Sub::Uplevel overrides CORE::GLOBAL::caller temporarily for the scope of
Packit cde0b4
    each uplevel call. It does its best to work with any previously existing
Packit cde0b4
    CORE::GLOBAL::caller (both when Sub::Uplevel is first loaded and within
Packit cde0b4
    each uplevel call) such as from Contextual::Return or Hook::LexWrap.
Packit cde0b4
Packit cde0b4
    However, if you are routinely using multiple modules that override
Packit cde0b4
    CORE::GLOBAL::caller, you are probably asking for trouble.
Packit cde0b4
Packit cde0b4
    You should load Sub::Uplevel as early as possible within your program.
Packit cde0b4
    As with all CORE::GLOBAL overloading, the overload will not affect
Packit cde0b4
    modules that have already been compiled prior to the overload. One
Packit cde0b4
    module that often is unavoidably loaded prior to Sub::Uplevel is
Packit cde0b4
    Exporter. To forcibly recompile Exporter (and Exporter::Heavy) after
Packit cde0b4
    loading Sub::Uplevel, use it with the ":aggressive" tag:
Packit cde0b4
Packit cde0b4
        use Sub::Uplevel qw/:aggressive/;
Packit cde0b4
Packit cde0b4
    The private function "Sub::Uplevel::_force_reload()" may be passed a
Packit cde0b4
    list of additional modules to reload if ":aggressive" is not aggressive
Packit cde0b4
    enough. Reloading modules may break things, so only use this as a last
Packit cde0b4
    resort.
Packit cde0b4
Packit cde0b4
    As of version 0.20, Sub::Uplevel requires Perl 5.6 or greater.
Packit cde0b4
Packit cde0b4
HISTORY
Packit cde0b4
    Those who do not learn from HISTORY are doomed to repeat it.
Packit cde0b4
Packit cde0b4
    The lesson here is simple: Don't sit next to a Tcl programmer at the
Packit cde0b4
    dinner table.
Packit cde0b4
Packit cde0b4
THANKS
Packit cde0b4
    Thanks to Brent Welch, Damian Conway and Robin Houston.
Packit cde0b4
Packit cde0b4
    See http://www.perl.com/perl/misc/Artistic.html
Packit cde0b4
Packit cde0b4
SEE ALSO
Packit cde0b4
    PadWalker (for the similar idea with lexicals), Hook::LexWrap, Tcl's
Packit cde0b4
    uplevel() at http://www.scriptics.com/man/tcl8.4/TclCmd/uplevel.htm
Packit cde0b4
Packit cde0b4
SUPPORT
Packit cde0b4
  Bugs / Feature Requests
Packit cde0b4
    Please report any bugs or feature requests through the issue tracker at
Packit cde0b4
    <https://github.com/Perl-Toolchain-Gang/Sub-Uplevel/issues>. You will be
Packit cde0b4
    notified automatically of any progress on your issue.
Packit cde0b4
Packit cde0b4
  Source Code
Packit cde0b4
    This is open source software. The code repository is available for
Packit cde0b4
    public review and contribution under the terms of the license.
Packit cde0b4
Packit cde0b4
    <https://github.com/Perl-Toolchain-Gang/Sub-Uplevel>
Packit cde0b4
Packit cde0b4
      git clone https://github.com/Perl-Toolchain-Gang/Sub-Uplevel.git
Packit cde0b4
Packit cde0b4
AUTHORS
Packit cde0b4
    *   Michael Schwern <mschwern@cpan.org>
Packit cde0b4
Packit cde0b4
    *   David Golden <dagolden@cpan.org>
Packit cde0b4
Packit cde0b4
CONTRIBUTORS
Packit cde0b4
    *   Adam Kennedy <adamk@cpan.org>
Packit cde0b4
Packit cde0b4
    *   Alexandr Ciornii <alexchorny@gmail.com>
Packit cde0b4
Packit cde0b4
    *   David Golden <xdg@xdg.me>
Packit cde0b4
Packit cde0b4
    *   Graham Ollis <plicease@cpan.org>
Packit cde0b4
Packit cde0b4
    *   J. Nick Koston <nick@cpanel.net>
Packit cde0b4
Packit cde0b4
    *   Michael Gray <mg13@sanger.ac.uk>
Packit cde0b4
Packit cde0b4
COPYRIGHT AND LICENSE
Packit cde0b4
    This software is copyright (c) 2017 by Michael Schwern and David Golden.
Packit cde0b4
Packit cde0b4
    This is free software; you can redistribute it and/or modify it under
Packit cde0b4
    the same terms as the Perl 5 programming language system itself.
Packit cde0b4