]> git.vpit.fr Git - perl/modules/Scope-Upper.git/blob - lib/Scope/Upper.pm
Implement uid() and validate_uid()
[perl/modules/Scope-Upper.git] / lib / Scope / Upper.pm
1 package Scope::Upper;
2
3 use strict;
4 use warnings;
5
6 =head1 NAME
7
8 Scope::Upper - Act on upper scopes.
9
10 =head1 VERSION
11
12 Version 0.17
13
14 =cut
15
16 our $VERSION;
17 BEGIN {
18  $VERSION = '0.17';
19 }
20
21 =head1 SYNOPSIS
22
23 L</reap>, L</localize>, L</localize_elem>, L</localize_delete> and L</WORDS> :
24
25     package Scope;
26
27     use Scope::Upper qw<reap localize localize_elem localize_delete :words>;
28
29     sub new {
30      my ($class, $name) = @_;
31
32      localize '$tag' => bless({ name => $name }, $class) => UP;
33
34      reap { print Scope->tag->name, ": end\n" } UP;
35     }
36
37     # Get the tag stored in the caller namespace
38     sub tag {
39      my $l   = 0;
40      my $pkg = __PACKAGE__;
41      $pkg    = caller $l++ while $pkg eq __PACKAGE__;
42
43      no strict 'refs';
44      ${$pkg . '::tag'};
45     }
46
47     sub name { shift->{name} }
48
49     # Locally capture warnings and reprint them with the name prefixed
50     sub catch {
51      localize_elem '%SIG', '__WARN__' => sub {
52       print Scope->tag->name, ': ', @_;
53      } => UP;
54     }
55
56     # Locally clear @INC
57     sub private {
58      for (reverse 0 .. $#INC) {
59       # First UP is the for loop, second is the sub boundary
60       localize_delete '@INC', $_ => UP UP;
61      }
62     }
63
64     ...
65
66     package UserLand;
67
68     {
69      Scope->new("top");      # initializes $UserLand::tag
70
71      {
72       Scope->catch;
73       my $one = 1 + undef;   # prints "top: Use of uninitialized value..."
74
75       {
76        Scope->private;
77        eval { require Cwd };
78        print $@;             # prints "Can't locate Cwd.pm in @INC (@INC contains:) at..."
79       }
80
81       require Cwd;           # loads Cwd.pm
82      }
83
84     }                        # prints "top: done"
85
86 L</unwind> and L</want_at> :
87
88     package Try;
89
90     use Scope::Upper qw<unwind want_at :words>;
91
92     sub try (&) {
93      my @result = shift->();
94      my $cx = SUB UP; # Point to the sub above this one
95      unwind +(want_at($cx) ? @result : scalar @result) => $cx;
96     }
97
98     ...
99
100     sub zap {
101      try {
102       my @things = qw<a b c>;
103       return @things; # returns to try() and then outside zap()
104       # not reached
105      };
106      # not reached
107     }
108
109     my @stuff = zap(); # @stuff contains qw<a b c>
110     my $stuff = zap(); # $stuff contains 3
111
112 L</uplevel> :
113
114     package Uplevel;
115
116     use Scope::Upper qw<uplevel CALLER>;
117
118     sub target {
119      faker(@_);
120     }
121
122     sub faker {
123      uplevel {
124       my $sub = (caller 0)[3];
125       print "$_[0] from $sub()";
126      } @_ => CALLER(1);
127     }
128
129     target('hello'); # "hello from Uplevel::target()"
130
131 L</uid> and L</validate_uid> :
132
133     use Scope::Upper qw<uid validate_uid>;
134
135     my $uid;
136
137     {
138      $uid = uid();
139      {
140       if ($uid eq uid(UP)) { # yes
141        ...
142       }
143       if (validate_uid($uid)) { # yes
144        ...
145       }
146      }
147     }
148
149     if (validate_uid($uid)) { # no
150      ...
151     }
152
153 =head1 DESCRIPTION
154
155 This module lets you defer actions I<at run-time> that will take place when the control flow returns into an upper scope.
156 Currently, you can:
157
158 =over 4
159
160 =item *
161
162 hook an upper scope end with L</reap> ;
163
164 =item *
165
166 localize variables, array/hash values or deletions of elements in higher contexts with respectively L</localize>, L</localize_elem> and L</localize_delete> ;
167
168 =item *
169
170 return values immediately to an upper level with L</unwind>, and know which context was in use then with L</want_at> ;
171
172 =item *
173
174 execute a subroutine in the setting of an upper subroutine stack frame with L</uplevel> ;
175
176 =item *
177
178 uniquely identify contextes with L</uid> and L</validate_uid>.
179
180 =back
181
182 =head1 FUNCTIONS
183
184 In all those functions, C<$context> refers to the target scope.
185
186 You have to use one or a combination of L</WORDS> to build the C<$context> passed to these functions.
187 This is needed in order to ensure that the module still works when your program is ran in the debugger.
188 The only thing you can assume is that it is an I<absolute> indicator of the frame, which means that you can safely store it at some point and use it when needed, and it will still denote the original scope.
189
190 =cut
191
192 BEGIN {
193  require XSLoader;
194  XSLoader::load(__PACKAGE__, $VERSION);
195 }
196
197 =head2 C<reap $callback, $context>
198
199 Adds a destructor that calls C<$callback> (in void context) when the upper scope represented by C<$context> ends.
200
201 =head2 C<localize $what, $value, $context>
202
203 Introduces a C<local> delayed to the time of first return into the upper scope denoted by C<$context>.
204 C<$what> can be :
205
206 =over 4
207
208 =item *
209
210 A glob, in which case C<$value> can either be a glob or a reference.
211 L</localize> follows then the same syntax as C<local *x = $value>.
212 For example, if C<$value> is a scalar reference, then the C<SCALAR> slot of the glob will be set to C<$$value> - just like C<local *x = \1> sets C<$x> to C<1>.
213
214 =item *
215
216 A string beginning with a sigil, representing the symbol to localize and to assign to.
217 If the sigil is C<'$'>, L</localize> follows the same syntax as C<local $x = $value>, i.e. C<$value> isn't dereferenced.
218 For example,
219
220     localize '$x', \'foo' => HERE;
221
222 will set C<$x> to a reference to the string C<'foo'>.
223 Other sigils (C<'@'>, C<'%'>, C<'&'> and C<'*'>) require C<$value> to be a reference of the corresponding type.
224
225 When the symbol is given by a string, it is resolved when the actual localization takes place and not when L</localize> is called.
226 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 L</localize> call was compiled.
227 For example,
228
229     {
230      package Scope;
231      sub new { localize '$tag', $_[0] => UP }
232     }
233
234     {
235      package Tool;
236      {
237       Scope->new;
238       ...
239      }
240     }
241
242 will localize C<$Tool::tag> and not C<$Scope::tag>.
243 If you want the other behaviour, you just have to specify C<$what> as a glob or a qualified name.
244
245 Note that if C<$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.
246 This situation never arises with C<local> because it only compiles when the localized variable is already declared.
247 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.
248
249 =back
250
251 =head2 C<localize_elem $what, $key, $value, $context>
252
253 Introduces a C<local $what[$key] = $value> or C<local $what{$key} = $value> delayed to the time of first return into the upper scope denoted by C<$context>.
254 Unlike L</localize>, C<$what> must be a string and the type of localization is inferred from its sigil.
255 The two only valid types are array and hash ; for anything besides those, L</localize_elem> will throw an exception.
256 C<$key> is either an array index or a hash key, depending of which kind of variable you localize.
257
258 If C<$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.
259
260 =head2 C<localize_delete $what, $key, $context>
261
262 Introduces the deletion of a variable or an array/hash element delayed to the time of first return into the upper scope denoted by C<$context>.
263 C<$what> can be:
264
265 =over 4
266
267 =item *
268
269 A glob, in which case C<$key> is ignored and the call is equivalent to C<local *x>.
270
271 =item *
272
273 A string beginning with C<'@'> or C<'%'>, for which the call is equivalent to respectiveley C<local $a[$key]; delete $a[$key]> and C<local $h{$key}; delete $h{$key}>.
274
275 =item *
276
277 A string beginning with C<'&'>, which more or less does C<undef &func> in the upper scope.
278 It's actually more powerful, as C<&func> won't even C<exists> anymore.
279 C<$key> is ignored.
280
281 =back
282
283 =head2 C<unwind @values, $context>
284
285 Returns C<@values> I<from> the context pointed by C<$context>, i.e. from the subroutine, eval or format at or just above C<$context>, and immediately restart the program flow at this point - thus effectively returning to an upper scope.
286
287 The upper context isn't coerced onto C<@values>, which is hence always evaluated in list context.
288 This means that
289
290     my $num = sub {
291      my @a = ('a' .. 'z');
292      unwind @a => HERE;
293      # not reached
294     }->();
295
296 will set C<$num> to C<'z'>.
297 You can use L</want_at> to handle these cases.
298
299 =head2 C<want_at $context>
300
301 Like C<wantarray>, but for the subroutine/eval/format at or just above C<$context>.
302
303 The previous example can then be "corrected" :
304
305     my $num = sub {
306      my @a = ('a' .. 'z');
307      unwind +(want_at(HERE) ? @a : scalar @a) => HERE;
308      # not reached
309     }->();
310
311 will rightfully set C<$num> to C<26>.
312
313 =head2 C<uplevel $code, @args, $context>
314
315 Executes the code reference C<$code> with arguments C<@args> as if it were located at the subroutine stack frame pointed by C<$context>, effectively fooling C<caller> and C<die> into believing that the call actually happened higher in the stack.
316 The code is executed in the context of the C<uplevel> call, and what it returns is returned as-is by C<uplevel>.
317
318     sub target {
319      faker(@_);
320     }
321
322     sub faker {
323      uplevel {
324       map { 1 / $_ } @_;
325      } @_ => CALLER(1);
326     }
327
328     my @inverses = target(1, 2, 4); # @inverses contains (0, 0.5, 0.25)
329     my $count    = target(1, 2, 4); # $count is 3
330
331 L<Sub::Uplevel> also implements a pure-Perl version of C<uplevel>.
332 Both are identical, with the following caveats :
333
334 =over 4
335
336 =item *
337
338 The L<Sub::Uplevel> implementation of C<uplevel> may execute a code reference in the context of B<any> upper stack frame.
339 The L<Scope::Upper> version can only uplevel to a B<subroutine> stack frame, and will croak if you try to target an C<eval> or a format.
340
341 =item *
342
343 Exceptions thrown from the code called by this version of C<uplevel> will not be caught by C<eval> blocks between the target frame and the uplevel call, while they will for L<Sub::Uplevel>'s version.
344 This means that :
345
346     eval {
347      sub {
348       local $@;
349       eval {
350        sub {
351         uplevel { die 'wut' } CALLER(2); # for Scope::Upper
352         # uplevel(3, sub { die 'wut' })  # for Sub::Uplevel
353        }->();
354       };
355       print "inner block: $@";
356       $@ and exit;
357      }->();
358     };
359     print "outer block: $@";
360
361 will print "inner block: wut..." with L<Sub::Uplevel> and "outer block: wut..." with L<Scope::Upper>.
362
363 =item *
364
365 L<Sub::Uplevel> globally overrides the Perl keyword C<caller>, while L<Scope::Upper> does not.
366
367 =back
368
369 A simple wrapper lets you mimic the interface of L<Sub::Uplevel/uplevel> :
370
371     use Scope::Upper;
372
373     sub uplevel {
374      my $frame = shift;
375      my $code  = shift;
376      my $cxt   = Scope::Upper::CALLER($frame);
377      &Scope::Upper::uplevel($code => @_ => $cxt);
378     }
379
380 Albeit the three exceptions listed above, it passes all the tests of L<Sub::Uplevel>.
381
382 =head2 C<uid $context>
383
384 Returns an unique identifier (UID) for the context (or dynamic scope) pointed by C<$context>, or for the current context if C<$context> is omitted.
385 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.
386
387     my $uid;
388
389     {
390      $uid = uid;
391      if ($uid eq uid()) { # yes, this is the same context
392       ...
393      }
394      {
395       if ($uid eq uid()) { # no, we are one scope below
396        ...
397       }
398       if ($uid eq uid(UP)) { # yes, UP points to the same scope as $uid
399        ...
400       }
401      }
402     }
403
404     # $uid is now invalid
405
406     {
407      if ($uid eq uid()) { # no, this is another block
408       ...
409      }
410     }
411
412 For example, each loop iteration gets its own UID :
413
414     my %uids;
415
416     for (1 .. 5) {
417      my $uid = uid;
418      $uids{$uid} = $_;
419     }
420
421     # %uids has 5 entries
422
423 The UIDs are not guaranteed to be numbers, so you must use the C<eq> operator to compare them.
424
425 To check whether a given UID is valid, you can use the L</validate_uid> function.
426
427 =head2 C<validate_uid $uid>
428
429 Returns true if and only if C<$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).
430
431     my $uid;
432
433     {
434      $uid = uid();
435      if (validate_uid($uid)) { # yes
436       ...
437      }
438      {
439       if (validate_uid($uid)) { # yes
440        ...
441       }
442      }
443     }
444
445     if (validate_uid($uid)) { # no
446      ...
447     }
448
449 =head1 CONSTANTS
450
451 =head2 C<SU_THREADSAFE>
452
453 True iff the module could have been built when thread-safety features.
454
455 =head1 WORDS
456
457 =head2 Constants
458
459 =head3 C<TOP>
460
461 Returns the context that currently represents the highest scope.
462
463 =head3 C<HERE>
464
465 The context of the current scope.
466
467 =head2 Getting a context from a context
468
469 For any of those functions, C<$from> is expected to be a context.
470 When omitted, it defaults to the the current context.
471
472 =head3 C<UP $from>
473
474 The context of the scope just above C<$from>.
475
476 =head3 C<SUB $from>
477
478 The context of the closest subroutine above C<$from>.
479 Note that C<$from> is returned if it is already a subroutine context ; hence C<SUB SUB == SUB>.
480
481 =head3 C<EVAL $from>
482
483 The context of the closest eval above C<$from>.
484 Note that C<$from> is returned if it is already an eval context ; hence C<EVAL EVAL == EVAL>.
485
486 =head2 Getting a context from a level
487
488 Here, C<$level> should denote a number of scopes above the current one.
489 When omitted, it defaults to C<0> and those functions return the same context as L</HERE>.
490
491 =head3 C<SCOPE $level>
492
493 The C<$level>-th upper context, regardless of its type.
494
495 =head3 C<CALLER $level>
496
497 The context of the C<$level>-th upper subroutine/eval/format.
498 It kind of corresponds to the context represented by C<caller $level>, but while e.g. C<caller 0> refers to the caller context, C<CALLER 0> will refer to the top scope in the current context.
499
500 =head2 Examples
501
502 Where L</reap> fires depending on the C<$cxt> :
503
504     sub {
505      eval {
506       sub {
507        {
508         reap \&cleanup => $cxt;
509         ...
510        }     # $cxt = SCOPE(0), or HERE
511        ...
512       }->(); # $cxt = SCOPE(1), or UP, or SUB, or CALLER, or CALLER(0)
513       ...
514      };      # $cxt = SCOPE(2), or UP UP, or UP SUB, or EVAL, or CALLER(1)
515      ...
516     }->();   # $cxt = SCOPE(3), or SUB UP SUB, or SUB EVAL, or CALLER(2)
517     ...
518
519 Where L</localize>, L</localize_elem> and L</localize_delete> act depending on the C<$cxt> :
520
521     sub {
522      eval {
523       sub {
524        {
525         localize '$x' => 1 => $cxt;
526         # $cxt = SCOPE(0), or HERE
527         ...
528        }
529        # $cxt = SCOPE(1), or UP, or SUB, or CALLER, or CALLER(0)
530        ...
531       }->();
532       # $cxt = SCOPE(2), or UP UP, or UP SUB, or EVAL, or CALLER(1)
533       ...
534      };
535      # $cxt = SCOPE(3), or SUB UP SUB, or SUB EVAL, or CALLER(2)
536      ...
537     }->();
538     # $cxt = SCOPE(4), UP SUB UP SUB, or UP SUB EVAL, or UP CALLER(2), or TOP
539     ...
540
541 Where L</unwind>, L</want_at> and L</uplevel> point to depending on the C<$cxt>:
542
543     sub {
544      eval {
545       sub {
546        {
547         unwind @things => $cxt;     # or uplevel { ... } $cxt;
548         ...
549        }
550        ...
551       }->(); # $cxt = SCOPE(0 .. 1), or HERE, or UP, or SUB, or CALLER(0)
552       ...
553      };      # $cxt = SCOPE(2), or UP UP, or UP SUB, or EVAL, or CALLER(1) (*)
554      ...
555     }->();   # $cxt = SCOPE(3), or SUB UP SUB, or SUB EVAL, or CALLER(2)
556     ...
557
558     # (*) Note that uplevel() will croak if you pass that scope frame,
559     #     because it cannot target eval scopes.
560
561 =head1 EXPORT
562
563 The functions L</reap>, L</localize>, L</localize_elem>, L</localize_delete>,  L</unwind>, L</want_at> and L</uplevel> are only exported on request, either individually or by the tags C<':funcs'> and C<':all'>.
564
565 The constant L</SU_THREADSAFE> is also only exported on request, individually or by the tags C<':consts'> and C<':all'>.
566
567 Same goes for the words L</TOP>, L</HERE>, L</UP>, L</SUB>, L</EVAL>, L</SCOPE> and L</CALLER> that are only exported on request, individually or by the tags C<':words'> and C<':all'>.
568
569 =cut
570
571 use base qw<Exporter>;
572
573 our @EXPORT      = ();
574 our %EXPORT_TAGS = (
575  funcs  => [ qw<
576   reap
577   localize localize_elem localize_delete
578   unwind want_at
579   uplevel
580   uid validate_uid
581  > ],
582  words  => [ qw<TOP HERE UP SUB EVAL SCOPE CALLER> ],
583  consts => [ qw<SU_THREADSAFE> ],
584 );
585 our @EXPORT_OK   = map { @$_ } values %EXPORT_TAGS;
586 $EXPORT_TAGS{'all'} = [ @EXPORT_OK ];
587
588 =head1 CAVEATS
589
590 Be careful that local variables are restored in the reverse order in which they were localized.
591 Consider those examples:
592
593     local $x = 0;
594     {
595      reap sub { print $x } => HERE;
596      local $x = 1;
597      ...
598     }
599     # prints '0'
600     ...
601     {
602      local $x = 1;
603      reap sub { $x = 2 } => HERE;
604      ...
605     }
606     # $x is 0
607
608 The first case is "solved" by moving the C<local> before the C<reap>, and the second by using L</localize> instead of L</reap>.
609
610 The effects of L</reap>, L</localize> and L</localize_elem> can't cross C<BEGIN> blocks, hence calling those functions in C<import> is deemed to be useless.
611 This is an hopeless case because C<BEGIN> blocks are executed once while localizing constructs should do their job at each run.
612 However, it's possible to hook the end of the current scope compilation with L<B::Hooks::EndOfScope>.
613
614 Some rare oddities may still happen when running inside the debugger.
615 It may help to use a perl higher than 5.8.9 or 5.10.0, as they contain some context-related fixes.
616
617 Calling C<goto> to replace an L</uplevel>'d code frame does not work :
618
619 =over 4
620
621 =item *
622
623 for a C<perl> older than the 5.8 series ;
624
625 =item *
626
627 for a C<DEBUGGING> C<perl> run with debugging flags set (as in C<perl -D ...>) ;
628
629 =item *
630
631 when the runloop callback is replaced by another module.
632
633 =back
634
635 In those three cases, L</uplevel> will look for a C<goto &sub> statement in its callback and, if there is one, throw an exception before executing the code.
636
637 Moreover, in order to handle C<goto> statements properly, L</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 B<all> the code executed as the result of the L</uplevel> call (including subroutine calls inside the callback) when a C<goto> statement is found in the L</uplevel> callback.
638 Despite this shortcoming, this XS version of L</uplevel> should still run way faster than the pure-Perl version from L<Sub::Uplevel>.
639
640 =head1 DEPENDENCIES
641
642 L<XSLoader> (standard since perl 5.006).
643
644 =head1 SEE ALSO
645
646 L<perlfunc/local>, L<perlsub/"Temporary Values via local()">.
647
648 L<Alias>, L<Hook::Scope>, L<Scope::Guard>, L<Guard>.
649
650 L<Sub::Uplevel>.
651
652 L<Continuation::Escape> is a thin wrapper around L<Scope::Upper> that gives you a continuation passing style interface to L</unwind>.
653 It's easier to use, but it requires you to have control over the scope where you want to return.
654
655 L<Scope::Escape>.
656
657 =head1 AUTHOR
658
659 Vincent Pit, C<< <perl at profvince.com> >>, L<http://www.profvince.com>.
660
661 You can contact me by mail or on C<irc.perl.org> (vincent).
662
663 =head1 BUGS
664
665 Please report any bugs or feature requests to C<bug-scope-upper at rt.cpan.org>, or through the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Scope-Upper>.
666 I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
667
668 =head1 SUPPORT
669
670 You can find documentation for this module with the perldoc command.
671
672     perldoc Scope::Upper
673
674 Tests code coverage report is available at L<http://www.profvince.com/perl/cover/Scope-Upper>.
675
676 =head1 ACKNOWLEDGEMENTS
677
678 Inspired by Ricardo Signes.
679
680 Thanks to Shawn M. Moore for motivation.
681
682 =head1 COPYRIGHT & LICENSE
683
684 Copyright 2008,2009,2010,2011 Vincent Pit, all rights reserved.
685
686 This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
687
688 =cut
689
690 1; # End of Scope::Upper