]> git.vpit.fr Git - perl/modules/Scope-Upper.git/blobdiff - README
This is 0.34
[perl/modules/Scope-Upper.git] / README
diff --git a/README b/README
index e09bd1230a0ccc5c13b1fd17e90188bb56a9a6c5..1f7b09e86d7b75ee39dc27864831d88f2d89eecd 100644 (file)
--- a/README
+++ b/README
@@ -2,7 +2,7 @@ NAME
     Scope::Upper - Act on upper scopes.
 
 VERSION
-    Version 0.19
+    Version 0.34
 
 SYNOPSIS
     "reap", "localize", "localize_elem", "localize_delete" and "WORDS" :
@@ -148,13 +148,16 @@ DESCRIPTION
         higher contexts with respectively "localize", "localize_elem" and
         "localize_delete" ;
 
-    *   return values immediately to an upper level with "unwind", and know
-        which context was in use then with "want_at" ;
+    *   return values immediately to an upper level with "unwind", "yield"
+        and "leave" ;
+
+    *   gather information about an upper context with "want_at" and
+        "context_info" ;
 
     *   execute a subroutine in the setting of an upper subroutine stack
         frame with "uplevel" ;
 
-    *   uniquely identify contextes with "uid" and "validate_uid".
+    *   uniquely identify contexts with "uid" and "validate_uid".
 
 FUNCTIONS
     In all those functions, $context refers to the target scope.
@@ -246,7 +249,10 @@ FUNCTIONS
     will be vivified as soon as the localization occurs and emptied when it
     ends, although it will still exist in its glob.
 
-  "localize_delete $what, $key, $context"
+  "localize_delete"
+        localize_delete $what, $key;
+        localize_delete $what, $key, $context;
+
     Introduces the deletion of a variable or an array/hash element delayed
     to the time of first return into the upper scope denoted by $context.
     $what can be:
@@ -255,7 +261,7 @@ FUNCTIONS
         "local *x".
 
     *   A string beginning with '@' or '%', for which the call is equivalent
-        to respectiveley "local $a[$key]; delete $a[$key]" and "local
+        to respectively "local $a[$key]; delete $a[$key]" and "local
         $h{$key}; delete $h{$key}".
 
     *   A string beginning with '&', which more or less does "undef &func"
@@ -263,13 +269,15 @@ FUNCTIONS
         "exists" anymore. $key is ignored.
 
   "unwind"
-        unwind @values;
+        unwind;
         unwind @values, $context;
 
-    Returns @values *from* the context pointed by $context, i.e. from the
-    subroutine, eval or format at or just above $context, and immediately
-    restart the program flow at this point - thus effectively returning to
-    an upper scope.
+    Returns @values *from* the subroutine, eval or format context pointed by
+    or just above $context, and immediately restarts 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
@@ -282,14 +290,55 @@ FUNCTIONS
 
     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 restarts 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 "yield 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", but for the subroutine/eval/format at or just above
-    $context.
+    Like "wantarray" in perlfunc, but for the subroutine, eval or format
+    context located at or just above $context.
 
-    The previous example can then be "corrected" :
+    It can be used to revise the example showed in "unwind" :
 
         my $num = sub {
          my @a = ('a' .. 'z');
@@ -299,13 +348,57 @@ FUNCTIONS
 
     will rightfully set $num to 26.
 
-  "uplevel $code, @args, $context"
+  "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 returned values 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;
-        my @ret = uplevel { ... } @args, $context;
+        my @ret = uplevel { my @args = @_; ...; return @ret } @args, $context;
         my @ret = &uplevel($callback, @args, $context);
 
-    Executes the code reference $code with arguments @args as if it were
+    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
@@ -324,6 +417,9 @@ FUNCTIONS
         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 :
 
@@ -468,27 +564,35 @@ WORDS
 
   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.
+    omitted, it defaults to the current context.
 
    "UP"
         my $upper_context = UP;
         my $upper_context = UP $from;
 
-    The context of the scope just above $from.
+    The context of the scope just above $from. If $from points to the
+    top-level scope in the current stack, then a warning is emitted and
+    $from is returned (see "DIAGNOSTICS" for details).
 
    "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".
+    The context of the closest subroutine above $from. If $from already
+    designates a subroutine context, then it is returned as-is ; hence "SUB
+    SUB == SUB". If no subroutine context is present in the call stack, then
+    a warning is emitted and the current context is returned (see
+    "DIAGNOSTICS" for details).
 
    "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".
+    The context of the closest eval above $from. If $from already designates
+    an eval context, then it is returned as-is ; hence "EVAL EVAL == EVAL".
+    If no eval context is present in the call stack, then a warning is
+    emitted and the current context is returned (see "DIAGNOSTICS" for
+    details).
 
   Getting a context from a level
     Here, $level should denote a number of scopes above the current one.
@@ -499,7 +603,10 @@ WORDS
         my $context = SCOPE;
         my $context = SCOPE $level;
 
-    The $level-th upper context, regardless of its type.
+    The $level-th upper context, regardless of its type. If $level points
+    above the top-level scope in the current stack, then a warning is
+    emitted and the top-level context is returned (see "DIAGNOSTICS" for
+    details).
 
    "CALLER"
         my $context = CALLER;
@@ -508,7 +615,9 @@ WORDS
     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.
+    the top scope in the current context. If $level points above the
+    top-level scope in the current stack, then a warning is emitted and the
+    top-level context is returned (see "DIAGNOSTICS" for details).
 
   Examples
     Where "reap" fires depending on the $cxt :
@@ -551,13 +660,15 @@ WORDS
         # $cxt = SCOPE(4), UP SUB UP SUB = UP SUB EVAL = UP CALLER(2) = TOP
         ...
 
-    Where "unwind", "want_at" and "uplevel" point to depending on the $cxt:
+    Where "unwind", "yield", "want_at", "context_info" and "uplevel" point
+    to depending on the $cxt:
 
         sub {
          eval {
           sub {
            {
-            unwind @things => $cxt;   # or uplevel { ... } $cxt;
+            unwind @things => $cxt;   # or yield @things => $cxt
+                                      # or uplevel { ... } $cxt
             ...
            }
            ...
@@ -571,10 +682,25 @@ WORDS
         # (*) Note that uplevel() will croak if you pass that scope frame,
         #     because it cannot target eval scopes.
 
+DIAGNOSTICS
+  "Cannot target a scope outside of the current stack"
+    This warning is emitted when "UP", "SCOPE" or "CALLER" end up pointing
+    to a context that is above the top-level context of the current stack.
+    It indicates that you tried to go higher than the main scope, or to
+    point across a "DESTROY" method, a signal handler, an overloaded or tied
+    method call, a "require" statement or a "sort" callback. In this case,
+    the resulting context is the highest reachable one.
+
+  "No targetable %s scope in the current stack"
+    This warning is emitted when you ask for an "EVAL" or "SUB" context and
+    no such scope can be found in the call stack. The resulting context is
+    the current one.
+
 EXPORT
     The functions "reap", "localize", "localize_elem", "localize_delete",
-    "unwind", "want_at" and "uplevel" are only exported on request, either
-    individually or by the tags ':funcs' and ':all'.
+    "unwind", "yield", "leave", "want_at", "context_info" and "uplevel" are
+    only exported on request, either individually or by the tags ':funcs'
+    and ':all'.
 
     The constant "SU_THREADSAFE" is also only exported on request,
     individually or by the tags ':consts' and ':all'.
@@ -584,6 +710,11 @@ EXPORT
     ':words' and ':all'.
 
 CAVEATS
+    It is not possible to act upon a scope that belongs to another perl
+    'stack', i.e. to target a scope across a "DESTROY" method, a signal
+    handler, an overloaded or tied method call, a "require" statement or a
+    "sort" callback.
+
     Be careful that local variables are restored in the reverse order in
     which they were localized. Consider those examples:
 
@@ -631,15 +762,25 @@ CAVEATS
 
     Moreover, in order to handle "goto" statements properly, "uplevel"
     currently has to suffer a run-time overhead proportional to the size of
-    the the callback in every case (with a small ratio), and proportional to
-    the size of all the code executed as the result of the "uplevel" call
+    the callback in every case (with a small ratio), and proportional to the
+    size of all the code executed as the result of the "uplevel" call
     (including subroutine calls inside the callback) when a "goto" statement
     is found in the "uplevel" callback. Despite this shortcoming, this XS
     version of "uplevel" should still run way faster than the pure-Perl
     version from Sub::Uplevel.
 
+    Starting from "perl" 5.19.4, it is unfortunately no longer possible to
+    reliably throw exceptions from "uplevel"'d code while the debugger is in
+    use. This may be solved in a future version depending on how the core
+    evolves.
+
 DEPENDENCIES
-    XSLoader (standard since perl 5.006).
+    perl 5.6.1.
+
+    A C compiler. This module may happen to build with a C++ compiler as
+    well, but don't rely on it, as no guarantee is made in this regard.
+
+    XSLoader (core since perl 5.6.0).
 
 SEE ALSO
     "local" in perlfunc, "Temporary Values via local()" in perlsub.
@@ -656,7 +797,7 @@ SEE ALSO
     Scope::Escape.
 
 AUTHOR
-    Vincent Pit, "<perl at profvince.com>", <http://www.profvince.com>.
+    Vincent Pit "<vpit at cpan.org>".
 
     You can contact me by mail or on "irc.perl.org" (vincent).
 
@@ -672,16 +813,19 @@ SUPPORT
 
         perldoc Scope::Upper
 
-    Tests code coverage report is available at
-    <http://www.profvince.com/perl/cover/Scope-Upper>.
-
 ACKNOWLEDGEMENTS
     Inspired by Ricardo Signes.
 
+    The reimplementation of a large part of this module for perl 5.24 was
+    provided by David Mitchell. His work was sponsored by the Perl 5 Core
+    Maintenance Grant from The Perl Foundation.
+
     Thanks to Shawn M. Moore for motivation.
 
 COPYRIGHT & LICENSE
-    Copyright 2008,2009,2010,2011,2012 Vincent Pit, all rights reserved.
+    Copyright
+    2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2021,2023
+    Vincent Pit, all rights reserved.
 
     This program is free software; you can redistribute it and/or modify it
     under the same terms as Perl itself.