]> git.vpit.fr Git - perl/modules/Scope-Upper.git/blob - README
This is 0.07
[perl/modules/Scope-Upper.git] / README
1 NAME
2     Scope::Upper - Act on upper scopes.
3
4 VERSION
5     Version 0.07
6
7 SYNOPSIS
8         package X;
9
10         use Scope::Upper qw/reap localize localize_elem localize_delete :words/;
11
12         sub desc { shift->{desc} }
13
14         sub set_tag {
15          my ($desc) = @_;
16
17          # First localize $x so that it gets destroyed last
18          localize '$x' => bless({ desc => $desc }, __PACKAGE__) => UP; # one scope up
19
20          reap sub {
21           my $pkg = caller;
22           my $x = do { no strict 'refs'; ${$pkg.'::x'} }; # Get the $x in the scope
23           print $x->desc . ": done\n";
24          } => SCOPE 1; # same as UP here
25
26          localize_elem '%SIG', '__WARN__' => sub {
27           my $pkg = caller;
28           my $x = do { no strict 'refs'; ${$pkg.'::x'} }; # Get the $x in the scope
29           CORE::warn($x->desc . ': ' . join('', @_));
30          } => UP CALLER 0; # same as UP here
31
32          # delete last @ARGV element
33          localize_delete '@ARGV', -1 => UP SUB HERE; # same as UP here
34         }
35
36         package Y;
37
38         {
39          X::set_tag('pie');
40          # $x is now a X object, and @ARGV has one element less
41          warn 'what'; # warns "pie: what at ..."
42          ...
43         } # "pie: done" is printed
44
45         package Z;
46
47         use Scope::Upper qw/unwind want_at :words/;
48
49         sub try (&) {
50          my @result = shift->();
51          my $cx = SUB UP SUB;
52          unwind +(want_at($cx) ? @result : scalar @result) => $cx;
53         }
54
55         ...
56
57         sub zap {
58          try {
59           return @things; # returns to try() and then outside zap()
60          }
61         }
62
63         my @what = zap(); # @what contains @things
64
65 DESCRIPTION
66     This module lets you defer actions *at run-time* that will take place
67     when the control flow returns into an upper scope. Currently, you can:
68
69     *   hook an upper scope end with "reap" ;
70
71     *   localize variables, array/hash values or deletions of elements in
72         higher contexts with respectively "localize", "localize_elem" and
73         "localize_delete" ;
74
75     *   return values immediately to an upper level with "unwind", and know
76         which context was in use then with "want_at".
77
78 FUNCTIONS
79     In all those functions, $context refers to the target scope.
80
81     You have to use one or a combination of "WORDS" to build the $context
82     passed to these functions. This is needed in order to ensure that the
83     module still works when your program is ran in the debugger. The only
84     thing you can assume is that it is an *absolute* indicator of the frame,
85     which means that you can safely store it at some point and use it when
86     needed, and it will still denote the original scope.
87
88   "reap $callback, $context"
89     Add a destructor that calls $callback when the upper scope represented
90     by $context ends.
91
92   "localize $what, $value, $context"
93     A "local" delayed to the time of first return into the upper scope
94     denoted by $context. $what can be :
95
96     *   A glob, in which case $value can either be a glob or a reference.
97         "localize" follows then the same syntax as "local *x = $value". For
98         example, if $value is a scalar reference, then the "SCALAR" slot of
99         the glob will be set to $$value - just like "local *x = \1" sets $x
100         to 1.
101
102     *   A string beginning with a sigil, representing the symbol to localize
103         and to assign to. If the sigil is '$', "localize" follows the same
104         syntax as "local $x = $value", i.e. $value isn't dereferenced. For
105         example,
106
107             localize '$x', \'foo' => HERE;
108
109         will set $x to a reference to the string 'foo'. Other sigils ('@',
110         '%', '&' and '*') require $value to be a reference of the
111         corresponding type.
112
113         When the symbol is given by a string, it is resolved when the actual
114         localization takes place and not when "localize" is called. This
115         means that
116
117             sub tag { localize '$x', $_[0] => UP }
118
119         will localize in the caller's namespace.
120
121   "localize_elem $what, $key, $value, $context"
122     Similar to "localize" but for array and hash elements. If $what is a
123     glob, the slot to fill is determined from which type of reference $value
124     is ; otherwise it's inferred from the sigil. $key is either an array
125     index or a hash key, depending of which kind of variable you localize.
126
127   "localize_delete $what, $key, $context"
128     Similiar to "localize", but for deleting variables or array/hash
129     elements. $what can be:
130
131     *   A glob, in which case $key is ignored and the call is equivalent to
132         "local *x".
133
134     *   A string beginning with '@' or '%', for which the call is equivalent
135         to respectiveley "local $a[$key]; delete $a[$key]" and "local
136         $h{$key}; delete $h{$key}".
137
138     *   A string beginning with '&', which more or less does "undef &func"
139         in the upper scope. It's actually more powerful, as &func won't even
140         "exists" anymore. $key is ignored.
141
142   "unwind @values, $context"
143     Returns @values *from* the context pointed by $context, i.e. from the
144     subroutine, eval or format just above $context, and immediately restart
145     the program flow at this point - thus effectively returning to (or from,
146     depending on how you see it) an upper context.
147
148     The upper context isn't coerced onto @values, which is hence always
149     evaluated in list context. This means that
150
151         my $num = sub {
152          my @a = ('a' .. 'z');
153          unwind @a => HERE;
154         }->();
155
156     will set $num to 'z'. You can use "want_at" to handle these cases.
157
158   "want_at $context"
159     Like "wantarray", but for the subroutine/eval/format just above
160     $context.
161
162     The previous example can then be "corrected" :
163
164         my $num = sub {
165          my @a = ('a' .. 'z');
166          unwind +(want_at(HERE) ? @a : scalar @a) => HERE;
167         }->();
168
169     will righteously set $num to 26.
170
171 WORDS
172   Constants
173    "TOP"
174     Returns the context that currently represents the highest scope.
175
176    "HERE"
177     The context of the current scope.
178
179   Getting a context from a context
180     For any of those functions, $from is expected to be a context. When
181     omitted, it defaults to the the current context.
182
183    "UP $from"
184     The context of the scope just above $from.
185
186    "SUB $from"
187     The context of the closest subroutine above $from. Note that $from is
188     returned if it is already a subroutine context ; hence "SUB SUB == SUB".
189
190    "EVAL $from"
191     The context of the closest eval above $from. Note that $from is returned
192     if it is already an eval context ; hence "EVAL EVAL == EVAL".
193
194   Getting a context from a level
195     Here, $level should denote a number of scopes above the current one.
196     When omitted, it defaults to 0 and those functions return the same
197     context as "HERE".
198
199    "SCOPE $level"
200     The $level-th upper context, regardless of its type.
201
202    "CALLER $level"
203     The context of the $level-th upper subroutine/eval/format. It kind of
204     corresponds to the context represented by "caller $level", but while
205     e.g. "caller 0" refers to the caller context, "CALLER 0" will refer to
206     the top scope in the current context.
207
208   Examples
209     Where "reap" fires depending on the $cxt :
210
211         sub {
212          eval {
213           sub {
214            {
215             reap \&cleanup => $cxt;
216             ...
217            }     # $cxt = SCOPE(0), or HERE
218            ...
219           }->(); # $cxt = SCOPE(1), or UP, or SUB, or CALLER, or CALLER(0)
220           ...
221          };      # $cxt = SCOPE(2), or UP UP, or UP SUB, or EVAL, or CALLER(1)
222          ...
223         }->();   # $cxt = SCOPE(3), or SUB UP SUB, or SUB EVAL, or CALLER(2)
224         ...
225
226     Where "localize", "localize_elem" and "localize_delete" act depending on
227     the $cxt :
228
229         sub {
230          eval {
231           sub {
232            {
233             localize '$x' => 1 => $cxt;
234             # $cxt = SCOPE(0), or HERE
235             ...
236            }
237            # $cxt = SCOPE(1), or UP, or SUB, or CALLER, or CALLER(0)
238            ...
239           }->();
240           # $cxt = SCOPE(2), or UP UP, or UP SUB, or EVAL, or CALLER(1)
241           ...
242          };
243          # $cxt = SCOPE(3), or SUB UP SUB, or SUB EVAL, or CALLER(2)
244          ...
245         }->();
246         # $cxt = SCOPE(4), UP SUB UP SUB, or UP SUB EVAL, or UP CALLER(2), or TOP
247         ...
248
249     Where "unwind" and "want_at" point to depending on the $cxt:
250
251         sub {
252          eval {
253           sub {
254            {
255             unwind @things => $cxt;
256             ...
257            }
258            ...
259           }->(); # $cxt = SCOPE(0 .. 1), or HERE, or UP, or SUB, or CALLER(0)
260           ...
261          };      # $cxt = SCOPE(2), or UP UP, or UP SUB, or EVAL, or CALLER(1)
262          ...
263         }->();   # $cxt = SCOPE(3), or SUB UP SUB, or SUB EVAL, or CALLER(2)
264         ...
265
266 EXPORT
267     The functions "reap", "localize", "localize_elem", "localize_delete",
268     "unwind" and "want_at" are only exported on request, either individually
269     or by the tags ':funcs' and ':all'.
270
271     Same goes for the words "TOP", "HERE", "UP", "SUB", "EVAL", "SCOPE" and
272     "CALLER" that are only exported on request, individually or by the tags
273     ':words' and ':all'.
274
275 CAVEATS
276     Be careful that local variables are restored in the reverse order in
277     which they were localized. Consider those examples:
278
279         local $x = 0;
280         {
281          reap sub { print $x } => HERE;
282          local $x = 1;
283          ...
284         }
285         # prints '0'
286         ...
287         {
288          local $x = 1;
289          reap sub { $x = 2 } => HERE;
290          ...
291         }
292         # $x is 0
293
294     The first case is "solved" by moving the "local" before the "reap", and
295     the second by using "localize" instead of "reap".
296
297     The effects of "reap", "localize" and "localize_elem" can't cross
298     "BEGIN" blocks, hence calling those functions in "import" is deemed to
299     be useless. This is an hopeless case because "BEGIN" blocks are executed
300     once while localizing constructs should do their job at each run.
301     However, it's possible to hook the end of the current scope compilation
302     with B::Hooks::EndOfScope.
303
304     Some rare oddities may still happen when running inside the debugger. It
305     may help to use a perl higher than 5.8.9 or 5.10.0, as they contain some
306     context-related fixes.
307
308 DEPENDENCIES
309     XSLoader (standard since perl 5.006).
310
311 SEE ALSO
312     Alias, Hook::Scope, Scope::Guard, Guard.
313
314 AUTHOR
315     Vincent Pit, "<perl at profvince.com>", <http://www.profvince.com>.
316
317     You can contact me by mail or on "irc.perl.org" (vincent).
318
319 BUGS
320     Please report any bugs or feature requests to "bug-scope-upper at
321     rt.cpan.org", or through the web interface at
322     <http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Scope-Upper>. I will be
323     notified, and then you'll automatically be notified of progress on your
324     bug as I make changes.
325
326 SUPPORT
327     You can find documentation for this module with the perldoc command.
328
329         perldoc Scope::Upper
330
331     Tests code coverage report is available at
332     <http://www.profvince.com/perl/cover/Scope-Upper>.
333
334 ACKNOWLEDGEMENTS
335     Inspired by Ricardo Signes.
336
337     Thanks to Shawn M. Moore for motivation.
338
339 COPYRIGHT & LICENSE
340     Copyright 2008-2009 Vincent Pit, all rights reserved.
341
342     This program is free software; you can redistribute it and/or modify it
343     under the same terms as Perl itself.
344