+ "unwind"
+ unwind;
+ unwind @values, $context;
+
+ Returns @values *from* the subroutine, eval or format context pointed by
+ or just above $context, and immediately restart the program flow at this
+ point - thus effectively returning @values to an upper scope. If @values
+ is empty, then the $context parameter is optional and defaults to the
+ current context (making the call equivalent to a bare "return;") ;
+ otherwise it is mandatory.
+
+ The upper context isn't coerced onto @values, which is hence always
+ evaluated in list context. This means that
+
+ my $num = sub {
+ my @a = ('a' .. 'z');
+ unwind @a => HERE;
+ # not reached
+ }->();
+
+ will set $num to 'z'. You can use "want_at" to handle these cases.
+
+ "yield"
+ yield;
+ yield @values, $context;
+
+ Returns @values *from* the context pointed by or just above $context,
+ and immediately restart the program flow at this point. If @values is
+ empty, then the $context parameter is optional and defaults to the
+ current context ; otherwise it is mandatory.
+
+ "yield" differs from "unwind" in that it can target *any* upper scope
+ (besides a "s///e" substitution context) and not necessarily a sub, an
+ eval or a format. Hence you can use it to return values from a "do" or a
+ "map" block :
+
+ my $now = do {
+ local $@;
+ eval { require Time::HiRes } or yield time() => HERE;
+ Time::HiRes::time();
+ };
+
+ my @uniq = map {
+ yield if $seen{$_}++; # returns the empty list from the block
+ ...
+ } @things;
+
+ Like for "unwind", the upper context isn't coerced onto @values. You can
+ use the fifth value returned by "context_info" to handle context
+ coercion.
+
+ "leave"
+ leave;
+ leave @values;
+
+ Immediately returns @values from the current block, whatever it may be
+ (besides a "s///e" substitution context). "leave" is actually a synonym
+ for "unwind HERE", while "leave @values" is a synonym for "yield
+ @values, HERE".
+
+ Like for "yield", you can use the fifth value returned by "context_info"
+ to handle context coercion.
+
+ "want_at"
+ my $want = want_at;
+ my $want = want_at $context;
+
+ Like "wantarray" in perlfunc, but for the subroutine, eval or format
+ context located at or just above $context.
+
+ It can be used to revise the example showed in "unwind" :
+
+ my $num = sub {
+ my @a = ('a' .. 'z');
+ unwind +(want_at(HERE) ? @a : scalar @a) => HERE;
+ # not reached
+ }->();
+
+ will rightfully set $num to 26.
+
+ "context_info"
+ my ($package, $filename, $line, $subroutine, $hasargs,
+ $wantarray, $evaltext, $is_require, $hints, $bitmask,
+ $hinthash) = context_info $context;
+
+ Gives information about the context denoted by $context, akin to what
+ "caller" in perlfunc provides but not limited only to subroutine, eval
+ and format contexts. When $context is omitted, it defaults to the
+ current context.
+
+ The values returned are, in order :
+
+ * *(index 0)* : the namespace in use when the context was created ;
+
+ * *(index 1)* : the name of the file at the point where the context
+ was created ;
+
+ * *(index 2)* : the line number at the point where the context was
+ created ;
+
+ * *(index 3)* : the name of the subroutine called for this context, or
+ "undef" if this is not a subroutine context ;
+
+ * *(index 4)* : a boolean indicating whether a new instance of @_ was
+ set up for this context, or "undef" if this is not a subroutine
+ context ;
+
+ * *(index 5)* : the context (in the sense of "wantarray" in perlfunc)
+ in which the context (in our sense) is executed ;
+
+ * *(index 6)* : the contents of the string being compiled for this
+ context, or "undef" if this is not an eval context ;
+
+ * *(index 7)* : a boolean indicating whether this eval context was
+ created by "require", or "undef" if this is not an eval context ;
+
+ * *(index 8)* : the value of the lexical hints in use when the context
+ was created ;
+
+ * *(index 9)* : a bit string representing the warnings in use when the
+ context was created ;
+
+ * *(index 10)* : a reference to the lexical hints hash in use when the
+ context was created (only on perl 5.10 or greater).
+
+ "uplevel"
+ my @ret = uplevel { ...; return @ret };
+ my @ret = uplevel { my @args = @_; ...; return @ret } @args, $context;
+ my @ret = &uplevel($callback, @args, $context);
+
+ Executes the code reference $callback with arguments @args as if it were
+ located at the subroutine stack frame pointed by $context, effectively
+ fooling "caller" and "die" into believing that the call actually
+ happened higher in the stack. The code is executed in the context of the
+ "uplevel" call, and what it returns is returned as-is by "uplevel".
+
+ sub target {
+ faker(@_);
+ }
+
+ sub faker {
+ uplevel {
+ map { 1 / $_ } @_;
+ } @_ => CALLER(1);
+ }
+
+ my @inverses = target(1, 2, 4); # @inverses contains (0, 0.5, 0.25)
+ my $count = target(1, 2, 4); # $count is 3
+
+ Note that if @args is empty, then the $context parameter is optional and
+ defaults to the current context ; otherwise it is mandatory.
+
+ Sub::Uplevel also implements a pure-Perl version of "uplevel". Both are
+ identical, with the following caveats :
+
+ * The Sub::Uplevel implementation of "uplevel" may execute a code
+ reference in the context of any upper stack frame. The Scope::Upper
+ version can only uplevel to a subroutine stack frame, and will croak
+ if you try to target an "eval" or a format.
+
+ * Exceptions thrown from the code called by this version of "uplevel"
+ will not be caught by "eval" blocks between the target frame and the
+ uplevel call, while they will for Sub::Uplevel's version. This means
+ that :
+
+ eval {
+ sub {
+ local $@;
+ eval {
+ sub {
+ uplevel { die 'wut' } CALLER(2); # for Scope::Upper
+ # uplevel(3, sub { die 'wut' }) # for Sub::Uplevel
+ }->();
+ };
+ print "inner block: $@";
+ $@ and exit;
+ }->();
+ };
+ print "outer block: $@";
+
+ will print "inner block: wut..." with Sub::Uplevel and "outer block:
+ wut..." with Scope::Upper.
+
+ * Sub::Uplevel globally overrides the Perl keyword "caller", while
+ Scope::Upper does not.
+
+ A simple wrapper lets you mimic the interface of "uplevel" in
+ Sub::Uplevel :
+
+ use Scope::Upper;
+
+ sub uplevel {
+ my $frame = shift;
+ my $code = shift;
+ my $cxt = Scope::Upper::CALLER($frame);
+ &Scope::Upper::uplevel($code => @_ => $cxt);
+ }
+
+ Albeit the three exceptions listed above, it passes all the tests of
+ Sub::Uplevel.
+
+ "uid"
+ my $uid = uid;
+ my $uid = uid $context;
+
+ Returns an unique identifier (UID) for the context (or dynamic scope)
+ pointed by $context, or for the current context if $context is omitted.
+ This UID will only be valid for the life time of the context it
+ represents, and another UID will be generated next time the same scope
+ is executed.
+
+ my $uid;
+
+ {
+ $uid = uid;
+ if ($uid eq uid()) { # yes, this is the same context
+ ...
+ }
+ {
+ if ($uid eq uid()) { # no, we are one scope below
+ ...
+ }
+ if ($uid eq uid(UP)) { # yes, UP points to the same scope as $uid
+ ...
+ }
+ }
+ }
+
+ # $uid is now invalid
+
+ {
+ if ($uid eq uid()) { # no, this is another block
+ ...
+ }
+ }
+
+ For example, each loop iteration gets its own UID :
+
+ my %uids;
+
+ for (1 .. 5) {
+ my $uid = uid;
+ $uids{$uid} = $_;
+ }
+
+ # %uids has 5 entries
+
+ The UIDs are not guaranteed to be numbers, so you must use the "eq"
+ operator to compare them.
+
+ To check whether a given UID is valid, you can use the "validate_uid"
+ function.
+
+ "validate_uid"
+ my $is_valid = validate_uid $uid;
+
+ Returns true if and only if $uid is the UID of a currently valid context
+ (that is, it designates a scope that is higher than the current one in
+ the call stack).
+
+ my $uid;
+
+ {
+ $uid = uid();
+ if (validate_uid($uid)) { # yes
+ ...
+ }
+ {
+ if (validate_uid($uid)) { # yes
+ ...
+ }
+ }
+ }
+
+ if (validate_uid($uid)) { # no
+ ...
+ }
+
+CONSTANTS
+ "SU_THREADSAFE"
+ True iff the module could have been built when thread-safety features.
+
+WORDS
+ Constants
+ "TOP"
+ my $top_context = TOP;
+
+ Returns the context that currently represents the highest scope.
+
+ "HERE"
+ my $current_context = HERE;
+
+ The context of the current scope.
+
+ Getting a context from a context
+ For any of those functions, $from is expected to be a context. When
+ omitted, it defaults to the the current context.
+
+ "UP"
+ my $upper_context = UP;
+ my $upper_context = UP $from;
+
+ The context of the scope just above $from.
+
+ "SUB"
+ my $sub_context = SUB;
+ my $sub_context = SUB $from;
+
+ The context of the closest subroutine above $from. Note that $from is
+ returned if it is already a subroutine context ; hence "SUB SUB == SUB".
+
+ "EVAL"
+ my $eval_context = EVAL;
+ my $eval_context = EVAL $from;
+
+ The context of the closest eval above $from. Note that $from is returned
+ if it is already an eval context ; hence "EVAL EVAL == EVAL".
+
+ Getting a context from a level
+ Here, $level should denote a number of scopes above the current one.
+ When omitted, it defaults to 0 and those functions return the same
+ context as "HERE".
+
+ "SCOPE"
+ my $context = SCOPE;
+ my $context = SCOPE $level;
+
+ The $level-th upper context, regardless of its type.
+
+ "CALLER"
+ my $context = CALLER;
+ my $context = CALLER $level;
+
+ The context of the $level-th upper subroutine/eval/format. It kind of
+ corresponds to the context represented by "caller $level", but while
+ e.g. "caller 0" refers to the caller context, "CALLER 0" will refer to
+ the top scope in the current context.
+
+ Examples
+ Where "reap" fires depending on the $cxt :
+
+ sub {
+ eval {
+ sub {
+ {
+ reap \&cleanup => $cxt;
+ ...
+ } # $cxt = SCOPE(0) = HERE
+ ...
+ }->(); # $cxt = SCOPE(1) = UP = SUB = CALLER(0)
+ ...
+ }; # $cxt = SCOPE(2) = UP UP = UP SUB = EVAL = CALLER(1)
+ ...
+ }->(); # $cxt = SCOPE(3) = SUB UP SUB = SUB EVAL = CALLER(2)
+ ...
+
+ Where "localize", "localize_elem" and "localize_delete" act depending on
+ the $cxt :
+
+ sub {
+ eval {
+ sub {
+ {
+ localize '$x' => 1 => $cxt;
+ # $cxt = SCOPE(0) = HERE
+ ...
+ }
+ # $cxt = SCOPE(1) = UP = SUB = CALLER(0)
+ ...
+ }->();
+ # $cxt = SCOPE(2) = UP UP = UP SUB = EVAL = CALLER(1)
+ ...
+ };
+ # $cxt = SCOPE(3) = SUB UP SUB = SUB EVAL = CALLER(2)
+ ...
+ }->();
+ # $cxt = SCOPE(4), UP SUB UP SUB = UP SUB EVAL = UP CALLER(2) = TOP
+ ...
+
+ Where "unwind", "yield", "want_at", "context_info" and "uplevel" point
+ to depending on the $cxt:
+
+ sub {
+ eval {
+ sub {
+ {
+ unwind @things => $cxt; # or yield @things => $cxt
+ # or uplevel { ... } $cxt
+ ...
+ }
+ ...
+ }->(); # $cxt = SCOPE(0) = SCOPE(1) = HERE = UP = SUB = CALLER(0)
+ ...
+ }; # $cxt = SCOPE(2) = UP UP = UP SUB = EVAL = CALLER(1) (*)
+ ...
+ }->(); # $cxt = SCOPE(3) = SUB UP SUB = SUB EVAL = CALLER(2)
+ ...
+
+ # (*) Note that uplevel() will croak if you pass that scope frame,
+ # because it cannot target eval scopes.