]> git.vpit.fr Git - perl/modules/Scope-Upper.git/commitdiff
This is 0.11 v0.11
authorVincent Pit <vince@profvince.com>
Fri, 16 Apr 2010 23:16:42 +0000 (01:16 +0200)
committerVincent Pit <vince@profvince.com>
Fri, 16 Apr 2010 23:16:42 +0000 (01:16 +0200)
Changes
META.yml
README
lib/Scope/Upper.pm

diff --git a/Changes b/Changes
index c31b88c3e61adcc2349974a803e3815c53057cce..6ba7ec3bac36bf55f2b87428d9a2e2f298790b08 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,5 +1,27 @@
 Revision history for Scope-Upper
 
+0.11    2010-04-16 23:20 UTC
+        + Chg : It's now forbiddent to pass a reference to a non-glob variable
+                as the localization target of localize(), localize_elem() and
+                localize_delete().
+        + Chg : localize_elem() now only accepts localization of arrays or hashs
+                elements. For other types, it used to be a synonym of localize.
+        + Chg : localize_elem() no longer accepts a glob as the target. You now
+                have to specify the variable as a string. This is because it was
+                impossible in this case to handle meaningfully the array or the
+                hash reference passed as the assigned value.
+        + Doc : The synopsys was revamped, and the rest of the documentation was
+                reviewed.
+        + Fix : [RT #55593] : Segfault when localizing hash or array element to
+                different package in different file.
+                Thanks Dagfinn Ilmari MannsÃ¥ker for reporting.
+        + Fix : [RT #56301] : reap loses eval context when dying naturally.
+                Thanks Andrew Main for reporting.
+        + Fix : Scope inconsistencies and segfaults when saving several
+                localizations into the same target scope.
+        + Fix : Stop skipping frames as a pop optimization. This caused breakage
+                under the debugger (and most likely outside as well).
+
 0.10    2010-01-18 23:50 UTC
         + Fix : Properly handle given/when on 5.10.
         + Fix : Some stack inconsistencies were fixed, though they were unlikely
index 36a52f84e5dcff14e6d2408228d04556da65d0ff..b5959cbfb3e427285a0f4a94ced461013921627b 100644 (file)
--- a/META.yml
+++ b/META.yml
@@ -1,6 +1,6 @@
 --- #YAML:1.0
 name:               Scope-Upper
-version:            0.10
+version:            0.11
 abstract:           Act on upper scopes.
 author:
     - Vincent Pit <perl@profvince.com>
diff --git a/README b/README
index 074581cbe7cf8130d2d391cbbc85974e775d7b8f..40d7734d222ec14c002f1266db88df263979809b 100644 (file)
--- a/README
+++ b/README
@@ -2,53 +2,81 @@ NAME
     Scope::Upper - Act on upper scopes.
 
 VERSION
-    Version 0.10
+    Version 0.11
 
 SYNOPSIS
-        package X;
+    "reap", "localize", "localize_elem", "localize_delete" and "WORDS" :
+
+        package Scope;
 
         use Scope::Upper qw/reap localize localize_elem localize_delete :words/;
 
-        sub desc { shift->{desc} }
+        sub new {
+         my ($class, $name) = @_;
+
+         localize '$tag' => bless({ name => $name }, $class) => UP;
+
+         reap { print Scope->tag->name, ": end\n" } UP;
+        }
 
-        sub set_tag {
-         my ($desc) = @_;
+        # Get the tag stored in the caller namespace
+        sub tag {
+         my $l   = 0;
+         my $pkg = __PACKAGE__;
+         $pkg    = caller $l++ while $pkg eq __PACKAGE__;
 
-         # First localize $x so that it gets destroyed last
-         localize '$x' => bless({ desc => $desc }, __PACKAGE__) => UP; # one scope up
+         no strict 'refs';
+         ${$pkg . '::tag'};
+        }
 
-         reap sub {
-          my $pkg = caller;
-          my $x = do { no strict 'refs'; ${$pkg.'::x'} }; # Get the $x in the scope
-          print $x->desc . ": done\n";
-         } => SCOPE 1; # same as UP here
+        sub name { shift->{name} }
 
+        # Locally capture warnings and reprint them with the name prefixed
+        sub catch {
          localize_elem '%SIG', '__WARN__' => sub {
-          my $pkg = caller;
-          my $x = do { no strict 'refs'; ${$pkg.'::x'} }; # Get the $x in the scope
-          CORE::warn($x->desc . ': ' . join('', @_));
-         } => UP CALLER 0; # same as UP here
+          print Scope->tag->name, ': ', @_;
+         } => UP;
+        }
 
-         # delete last @ARGV element
-         localize_delete '@ARGV', -1 => UP SUB HERE; # same as UP here
+        # Locally clear @INC
+        sub private {
+         for (reverse 0 .. $#INC) {
+          # First UP is the for loop, second is the sub boundary
+          localize_delete '@INC', $_ => UP UP;
+         }
         }
 
-        package Y;
+        ...
+
+        package UserLand;
 
         {
-         X::set_tag('pie');
-         # $x is now a X object, and @ARGV has one element less
-         warn 'what'; # warns "pie: what at ..."
-         ...
-        } # "pie: done" is printed
+         Scope->new("top");      # initializes $UserLand::tag
+
+         {
+          Scope->catch;
+          my $one = 1 + undef;   # prints "top: Use of uninitialized value..."
 
-        package Z;
+          {
+           Scope->private;
+           eval { require Cwd };
+           print $@;             # prints "Can't locate Cwd.pm in @INC (@INC contains:) at..."
+          }
+
+          require Cwd;           # loads Cwd.pm
+         }
+
+        }                        # prints "top: done"
+
+    "unwind" and "want_at" :
+
+        package Try;
 
         use Scope::Upper qw/unwind want_at :words/;
 
         sub try (&) {
          my @result = shift->();
-         my $cx = SUB UP SUB;
+         my $cx = SUB UP; # Point to the sub above this one
          unwind +(want_at($cx) ? @result : scalar @result) => $cx;
         }
 
@@ -56,13 +84,15 @@ SYNOPSIS
 
         sub zap {
          try {
+          my @things = qw/a b c/;
           return @things; # returns to try() and then outside zap()
           # not reached
-         }
+         };
          # not reached
         }
 
-        my @what = zap(); # @what contains @things
+        my @stuff = zap(); # @stuff contains qw/a b c/
+        my $stuff = zap(); # $stuff contains 3
 
 DESCRIPTION
     This module lets you defer actions *at run-time* that will take place
@@ -88,12 +118,12 @@ FUNCTIONS
     needed, and it will still denote the original scope.
 
   "reap $callback, $context"
-    Add a destructor that calls $callback (in void context) when the upper
+    Adds a destructor that calls $callback (in void context) when the upper
     scope represented by $context ends.
 
   "localize $what, $value, $context"
-    A "local" delayed to the time of first return into the upper scope
-    denoted by $context. $what can be :
+    Introduces a "local" delayed to the time of first return into the upper
+    scope denoted by $context. $what can be :
 
     *   A glob, in which case $value can either be a glob or a reference.
         "localize" follows then the same syntax as "local *x = $value". For
@@ -113,22 +143,54 @@ FUNCTIONS
         corresponding type.
 
         When the symbol is given by a string, it is resolved when the actual
-        localization takes place and not when "localize" is called. This
-        means that
-
-            sub tag { localize '$x', $_[0] => UP }
-
-        will localize in the caller's namespace.
+        localization takes place and not when "localize" is called. Thus, if
+        the symbol name is not qualified, it will refer to the variable in
+        the package where the localization actually takes place and not in
+        the one where the "localize" call was compiled. For example,
+
+            {
+             package Scope;
+             sub new { localize '$tag', $_[0] => UP }
+            }
+
+            {
+             package Tool;
+             {
+              Scope->new;
+              ...
+             }
+            }
+
+        will localize $Tool::tag and not $Scope::tag. If you want the other
+        behaviour, you just have to specify $what as a glob or a qualified
+        name.
+
+        Note that if $what is a string denoting a variable that wasn't
+        declared beforehand, the relevant slot will be vivified as needed
+        and won't be deleted from the glob when the localization ends. This
+        situation never arises with "local" because it only compiles when
+        the localized variable is already declared. Although I believe it
+        shouldn't be a problem as glob slots definedness is pretty much an
+        implementation detail, this behaviour may change in the future if
+        proved harmful.
 
   "localize_elem $what, $key, $value, $context"
-    Similar to "localize" but for array and hash elements. If $what is a
-    glob, the slot to fill is determined from which type of reference $value
-    is ; otherwise it's inferred from the sigil. $key is either an array
-    index or a hash key, depending of which kind of variable you localize.
+    Introduces a "local $what[$key] = $value" or "local $what{$key} =
+    $value" delayed to the time of first return into the upper scope denoted
+    by $context. Unlike "localize", $what must be a string and the type of
+    localization is inferred from its sigil. The two only valid types are
+    array and hash ; for anything besides those, "localize_elem" will throw
+    an exception. $key is either an array index or a hash key, depending of
+    which kind of variable you localize.
+
+    If $what is a string pointing to an undeclared variable, the variable
+    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"
-    Similiar to "localize", but for deleting variables or array/hash
-    elements. $what can be:
+    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:
 
     *   A glob, in which case $key is ignored and the call is equivalent to
         "local *x".
@@ -143,9 +205,9 @@ FUNCTIONS
 
   "unwind @values, $context"
     Returns @values *from* the context pointed by $context, i.e. from the
-    subroutine, eval or format just above $context, and immediately restart
-    the program flow at this point - thus effectively returning to (or from,
-    depending on how you see it) an upper context.
+    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.
 
     The upper context isn't coerced onto @values, which is hence always
     evaluated in list context. This means that
@@ -159,7 +221,7 @@ FUNCTIONS
     will set $num to 'z'. You can use "want_at" to handle these cases.
 
   "want_at $context"
-    Like "wantarray", but for the subroutine/eval/format just above
+    Like "wantarray", but for the subroutine/eval/format at or just above
     $context.
 
     The previous example can then be "corrected" :
@@ -320,6 +382,8 @@ DEPENDENCIES
     XSLoader (standard since perl 5.006).
 
 SEE ALSO
+    "local" in perlfunc, "Temporary Values via local()" in perlsub.
+
     Alias, Hook::Scope, Scope::Guard, Guard.
 
     Continuation::Escape is a thin wrapper around Scope::Upper that gives
@@ -327,6 +391,8 @@ SEE ALSO
     use, but it requires you to have control over the scope where you want
     to return.
 
+    Scope::Escape.
+
 AUTHOR
     Vincent Pit, "<perl at profvince.com>", <http://www.profvince.com>.
 
index c8e8650297ee091409c645fc82900cb2f6632540..ddbdc81a9bc7376e6e3ab6eea920c7fe61fbce57 100644 (file)
@@ -9,13 +9,13 @@ Scope::Upper - Act on upper scopes.
 
 =head1 VERSION
 
-Version 0.10
+Version 0.11
 
 =cut
 
 our $VERSION;
 BEGIN {
- $VERSION = '0.10';
+ $VERSION = '0.11';
 }
 
 =head1 SYNOPSIS