X-Git-Url: http://git.vpit.fr/?a=blobdiff_plain;f=lib%2FScope%2FUpper.pm;h=b114f2f0130e6faa46309a6d41c0e6260cd1888c;hb=780a9a13dd0a14aabed9c7c91613d4ad75190c9f;hp=4a9010059f7ce5112af17d57452539ae17458ff8;hpb=be1d59463692da1b5ef787aeffd0aedbef65664e;p=perl%2Fmodules%2FScope-Upper.git diff --git a/lib/Scope/Upper.pm b/lib/Scope/Upper.pm index 4a90100..b114f2f 100644 --- a/lib/Scope/Upper.pm +++ b/lib/Scope/Upper.pm @@ -1,5 +1,7 @@ package Scope::Upper; +use 5.006_001; + use strict; use warnings; @@ -9,13 +11,13 @@ Scope::Upper - Act on upper scopes. =head1 VERSION -Version 0.19 +Version 0.31 =cut our $VERSION; BEGIN { - $VERSION = '0.19'; + $VERSION = '0.31'; } =head1 SYNOPSIS @@ -170,7 +172,11 @@ localize variables, array/hash values or deletions of elements in higher context =item * -return values immediately to an upper level with L, L and L, and know which context was in use then with L ; +return values immediately to an upper level with L, L and L ; + +=item * + +gather information about an upper context with L and L ; =item * @@ -178,7 +184,7 @@ execute a subroutine in the setting of an upper subroutine stack frame with L and L. +uniquely identify contexts with L and L. =back @@ -286,7 +292,7 @@ A glob, in which case C<$key> is ignored and the call is equivalent to C or C<'%'>, for which the call is equivalent to respectiveley C and C. +A string beginning with C<'@'> or C<'%'>, for which the call is equivalent to respectively C and C. =item * @@ -301,7 +307,7 @@ C<$key> is ignored. unwind; unwind @values, $context; -Returns C<@values> I the subroutine, eval or format context pointed by or just above C<$context>, and immediately restart the program flow at this point - thus effectively returning C<@values> to an upper scope. +Returns C<@values> I the subroutine, eval or format context pointed by or just above C<$context>, and immediately restarts the program flow at this point - thus effectively returning C<@values> to an upper scope. If C<@values> is empty, then the C<$context> parameter is optional and defaults to the current context (making the call equivalent to a bare C) ; otherwise it is mandatory. The upper context isn't coerced onto C<@values>, which is hence always evaluated in list context. @@ -321,7 +327,7 @@ You can use L to handle these cases. yield; yield @values, $context; -Returns C<@values> I the context pointed by or just above C<$context>, and immediately restart the program flow at this point. +Returns C<@values> I the context pointed by or just above C<$context>, and immediately restarts the program flow at this point. If C<@values> is empty, then the C<$context> parameter is optional and defaults to the current context ; otherwise it is mandatory. L differs from L in that it can target I upper scope (besides a C substitution context) and not necessarily a sub, an eval or a format. @@ -339,6 +345,7 @@ Hence you can use it to return values from a C or a C block : } @things; Like for L, the upper context isn't coerced onto C<@values>. +You can use the fifth value returned by L to handle context coercion. =head2 C @@ -346,16 +353,18 @@ Like for L, the upper context isn't coerced onto C<@values>. leave @values; Immediately returns C<@values> from the current block, whatever it may be (besides a C substitution context). -C is actually a synonym for C, while C is a synonym for C. +C is actually a synonym for C, while C is a synonym for C. + +Like for L, you can use the fifth value returned by L to handle context coercion. =head2 C my $want = want_at; my $want = want_at $context; -Like C, but for the subroutine/eval/format at or just above C<$context>. +Like L, but for the subroutine, eval or format context located at or just above C<$context>. -The previous example can then be "corrected" : +It can be used to revise the example showed in L : my $num = sub { my @a = ('a' .. 'z'); @@ -365,6 +374,65 @@ The previous example can then be "corrected" : will rightfully set C<$num> to C<26>. +=head2 C + + my ($package, $filename, $line, $subroutine, $hasargs, + $wantarray, $evaltext, $is_require, $hints, $bitmask, + $hinthash) = context_info $context; + +Gives information about the context denoted by C<$context>, akin to what L provides but not limited only to subroutine, eval and format contexts. +When C<$context> is omitted, it defaults to the current context. + +The returned values are, in order : + +=over 4 + +=item * + +I<(index 0)> : the namespace in use when the context was created ; + +=item * + +I<(index 1)> : the name of the file at the point where the context was created ; + +=item * + +I<(index 2)> : the line number at the point where the context was created ; + +=item * + +I<(index 3)> : the name of the subroutine called for this context, or C if this is not a subroutine context ; + +=item * + +I<(index 4)> : a boolean indicating whether a new instance of C<@_> was set up for this context, or C if this is not a subroutine context ; + +=item * + +I<(index 5)> : the context (in the sense of L) in which the context (in our sense) is executed ; + +=item * + +I<(index 6)> : the contents of the string being compiled for this context, or C if this is not an eval context ; + +=item * + +I<(index 7)> : a boolean indicating whether this eval context was created by C, or C if this is not an eval context ; + +=item * + +I<(index 8)> : the value of the lexical hints in use when the context was created ; + +=item * + +I<(index 9)> : a bit string representing the warnings in use when the context was created ; + +=item * + +I<(index 10)> : a reference to the lexical hints hash in use when the context was created (only on perl 5.10 or greater). + +=back + =head2 C my @ret = uplevel { ...; return @ret }; @@ -537,7 +605,7 @@ The context of the current scope. =head2 Getting a context from a context For any of those functions, C<$from> is expected to be a context. -When omitted, it defaults to the the current context. +When omitted, it defaults to the current context. =head3 C @@ -545,6 +613,7 @@ When omitted, it defaults to the the current context. my $upper_context = UP $from; The context of the scope just above C<$from>. +If C<$from> points to the top-level scope in the current stack, then a warning is emitted and C<$from> is returned (see L for details). =head3 C @@ -552,7 +621,8 @@ The context of the scope just above C<$from>. my $sub_context = SUB $from; The context of the closest subroutine above C<$from>. -Note that C<$from> is returned if it is already a subroutine context ; hence C. +If C<$from> already designates a subroutine context, then it is returned as-is ; hence C. +If no subroutine context is present in the call stack, then a warning is emitted and the current context is returned (see L for details). =head3 C @@ -560,7 +630,8 @@ Note that C<$from> is returned if it is already a subroutine context ; hence C. -Note that C<$from> is returned if it is already an eval context ; hence C. +If C<$from> already designates an eval context, then it is returned as-is ; hence C. +If no eval context is present in the call stack, then a warning is emitted and the current context is returned (see L for details). =head2 Getting a context from a level @@ -573,6 +644,7 @@ When omitted, it defaults to C<0> and those functions return the same context as my $context = SCOPE $level; The C<$level>-th upper context, regardless of its type. +If C<$level> points above the top-level scope in the current stack, then a warning is emitted and the top-level context is returned (see L for details). =head3 C @@ -581,6 +653,7 @@ The C<$level>-th upper context, regardless of its type. The context of the C<$level>-th upper subroutine/eval/format. It kind of corresponds to the context represented by C, but while e.g. C refers to the caller context, C will refer to the top scope in the current context. +If C<$level> points above the top-level scope in the current stack, then a warning is emitted and the top-level context is returned (see L for details). =head2 Examples @@ -623,7 +696,7 @@ Where L, L and L act depending on t # $cxt = SCOPE(4), UP SUB UP SUB = UP SUB EVAL = UP CALLER(2) = TOP ... -Where L, L, L and L point to depending on the C<$cxt>: +Where L, L, L, L and L point to depending on the C<$cxt>: sub { eval { @@ -644,9 +717,22 @@ Where L, L, L and L point to depending on t # (*) Note that uplevel() will croak if you pass that scope frame, # because it cannot target eval scopes. +=head1 DIAGNOSTICS + +=head2 C + +This warning is emitted when L, L or L 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 C method, a signal handler, an overloaded or tied method call, a C statement or a C callback. +In this case, the resulting context is the highest reachable one. + +=head2 C + +This warning is emitted when you ask for an L or L context and no such scope can be found in the call stack. +The resulting context is the current one. + =head1 EXPORT -The functions L, L, L, L, L, L, L, L and L are only exported on request, either individually or by the tags C<':funcs'> and C<':all'>. +The functions L, L, L, L, L, L, L, L, L and L are only exported on request, either individually or by the tags C<':funcs'> and C<':all'>. The constant L is also only exported on request, individually or by the tags C<':consts'> and C<':all'>. @@ -662,7 +748,7 @@ our %EXPORT_TAGS = ( reap localize localize_elem localize_delete unwind yield leave - want_at + want_at context_info uplevel uid validate_uid > ], @@ -674,6 +760,8 @@ $EXPORT_TAGS{'all'} = [ @EXPORT_OK ]; =head1 CAVEATS +It is not possible to act upon a scope that belongs to another perl 'stack', i.e. to target a scope across a C method, a signal handler, an overloaded or tied method call, a C statement or a C callback. + Be careful that local variables are restored in the reverse order in which they were localized. Consider those examples: @@ -721,17 +809,20 @@ when the runloop callback is replaced by another module. In those three cases, L will look for a C statement in its callback and, if there is one, throw an exception before executing the code. -Moreover, in order to handle C statements properly, L 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 B the code executed as the result of the L call (including subroutine calls inside the callback) when a C statement is found in the L callback. +Moreover, in order to handle C statements properly, L currently has to suffer a run-time overhead proportional to the size of the callback in every case (with a small ratio), and proportional to the size of B the code executed as the result of the L call (including subroutine calls inside the callback) when a C statement is found in the L callback. Despite this shortcoming, this XS version of L should still run way faster than the pure-Perl version from L. +Starting from C 5.19.4, it is unfortunately no longer possible to reliably throw exceptions from L'd code while the debugger is in use. +This may be solved in a future version depending on how the core evolves. + =head1 DEPENDENCIES -L 5.6. +L 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. -L (core since perl 5.006). +L (core since perl 5.6.0). =head1 SEE ALSO @@ -748,7 +839,7 @@ L. =head1 AUTHOR -Vincent Pit, C<< >>, L. +Vincent Pit C<< >>. You can contact me by mail or on C (vincent). @@ -763,17 +854,18 @@ You can find documentation for this module with the perldoc command. perldoc Scope::Upper -Tests code coverage report is available at L. - =head1 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. =head1 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 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.