1 package Scope::Context;
11 use Scope::Upper 0.21 ();
15 Scope::Context - Object-oriented interface for inspecting or acting upon upper scope frames.
23 our $VERSION = '0.01';
32 # Create Scope::Context objects for different upper frames.
33 my ($block, $sub, $eval, $loop);
35 $block = Scope::Context->new;
36 $sub = $block->sub; # = $block->up
37 $eval = $block->eval; # = $block->up(2)
38 $loop = $eval->up; # = $block->up(3)
42 # This will throw an exception, since $block has expired.
43 $block->localize('$x' => 1);
46 # This prints "hello" when the eval block above ends.
47 $eval->reap(sub { print "hello\n" });
49 # Ignore $SIG{__DIE__} just for the loop body.
50 $loop->localize_delete('%SIG', '__DIE__');
52 # Execute the callback as if it ran in place of the sub.
53 my @values = $sub->uplevel(sub {
57 # Immediately return (1, 2, 3) from the sub, bypassing the eval.
58 $sub->unwind(@values, 3);
66 # unwind() returns here. "hello\n" was printed, and now
67 # $SIG{__DIE__} is undefined.
72 This class provides an object-oriented interface to L<Scope::Upper>'s functionalities.
73 A L<Scope::Context> object represents a currently active dynamic scope (or context), and encapsulates the corresponding L<Scope::Upper>-compatible context identifier.
74 All of L<Scope::Upper>'s functions are then made available as methods.
75 This gives you a prettier and safer interface when you are not reaching for extreme performance, but rest assured that the overhead of this module is minimal anyway.
77 The L<Scope::Context> methods actually do more than their subroutine counterparts from L<Scope::Upper> : before each call, the target context will be checked to ensure it is still active (which means that it is still present in the current call stack), and an exception will be thrown if you attempt to act on a context that has already expired.
82 $cxt = Scope::Context->new;
84 $cxt->reap(sub { print "hello\n });
86 will croak when L</reap> is called.
92 my $cxt = Scope::Context->new;
93 my $cxt = Scope::Context->new($scope_upper_cxt);
95 Creates a new immutable L<Scope::Context> object from the L<Scope::Upper>-comptabile context identifier C<$context>.
96 If omitted, C<$context> defaults to the current context.
101 my ($self, $cxt) = @_;
103 my $class = Scalar::Util::blessed($self);
104 unless (defined $class) {
105 $class = defined $self ? $self : __PACKAGE__;
108 $cxt = Scope::Upper::UP() unless defined $cxt;
112 uid => Scope::Upper::uid($cxt),
118 A synonym for L</new>.
134 my $scope_upper_cxt = $cxt->cxt;
136 Read-only accessor to the L<Scope::Upper> context identifier associated with the invocant.
142 Read-only accessor to the L<Scope::Upper> unique identifier representing the L<Scope::Upper> context associated with the invocant.
148 eval "sub $_ { \$_[0]->{$_} }; 1" or die $@ for qw<cxt uid>;
153 This class also overloads the C<==> operator, which will return true if and only if its two operands are L<Scope::Context> objects that have the same UID.
159 my ($left, $right) = @_;
161 unless (Scalar::Util::blessed($right) and $right->isa(__PACKAGE__)) {
162 $left->_croak('Cannot compare a Scope::Context object with something else');
165 $left->uid eq $right->uid;
172 my $is_valid = $cxt->is_valid;
174 Returns true if and only if the invocant is still valid (that is, it designates a scope that is higher on the call stack than the current scope).
178 sub is_valid { Scope::Upper::validate_uid($_[0]->uid) }
180 =head2 C<assert_valid>
184 Throws an exception if the invocant has expired and is no longer valid.
185 Returns true otherwise.
192 $self->_croak('Context has expired') unless $self->is_valid;
201 Returns the namespace in use when the scope denoted by the invocant begins.
207 Returns the name of the file where the scope denoted by the invocant belongs to.
213 Returns the line number where the scope denoted by the invocant begins.
219 Returns the name of the subroutine called for this context, or C<undef> if this is not a subroutine context.
221 =head2 C<sub_has_args>
225 Returns a boolean indicating whether a new instance of C<@_> was set up for this context, or C<undef> if this is not a subroutine context.
231 Returns the context (in the sense of L<perlfunc/wantarray>) in which the scope denoted by the invocant is executed.
237 Returns the contents of the string being compiled for this context, or C<undef> if this is not an eval context.
243 Returns a boolean indicating whether this eval context was created by C<require>, or C<undef> if this is not an eval context.
249 Returns the value of the lexical hints bit mask (available as C<$^H> at compile time) in use when the scope denoted by the invocant begins.
251 =head2 C<warnings_bits>
255 Returns the bit string representing the warnings (available as C<${^WARNING_BITS}> at compile time) in use when the scope denoted by the invocant begins.
261 Returns a reference to the lexical hints hash (available as C<%^H> at compile time) in use when the scope denoted by the invocant begins.
262 This method is available only on perl 5.10 and greater.
278 (hints_hash => 10) x ("$]" >= 5.010),
281 for my $name (sort { $infos{$a} <=> $infos{$b} } keys %infos) {
282 my $idx = $infos{$name};
288 \$self->assert_valid;
290 my \$info = \$self->{info};
291 \$info = \$self->{info} = [ Scope::Upper::context_info(\$self->cxt) ]
294 return \$info->[$idx];
303 my $want = $cxt->want;
305 Returns the Perl context (in the sense of C<wantarray> : C<undef> for void context, C<''> for scalar context, and true for list context) in which is executed the scope pointed by the invocant.
314 Scope::Upper::want_at($self->cxt);
319 my $up_cxt = $cxt->up;
320 my $up_cxt = $cxt->up($frames);
321 my $up_cxt = Scope::Context->up;
323 Returns a new L<Scope::Context> object pointing to the C<$frames>-th upper scope above the scope pointed by the invocant.
325 This method can also be invoked as a class method, in which case it is equivalent to calling L</up> on a L<Scope::Context> object representing the current context.
327 If omitted, C<$frames> defaults to C<1>.
332 my $up = Scope::Context->new->up(2); # = Scope::Context->up(2)
333 # $up points two contextes above this one, which is the sub.
341 my ($self, $frames) = @_;
344 if (Scalar::Util::blessed($self)) {
348 $cxt = Scope::Upper::UP(Scope::Upper::SUB());
351 $frames = 1 unless defined $frames;
353 $cxt = Scope::Upper::UP($cxt) for 1 .. $frames;
360 my $sub_cxt = $cxt->sub;
361 my $sub_cxt = $cxt->sub($frames);
362 my $sub_cxt = Scope::Context->sub;
364 Returns a new L<Scope::Context> object pointing to the C<$frames>-th subroutine scope above the scope pointed by the invocant.
366 This method can also be invoked as a class method, in which case it is equivalent to calling L</sub> on a L<Scope::Context> object for the current context.
368 If omitted, C<$frames> defaults to C<0>, which results in the closest sub enclosing the scope pointed by the invocant.
377 my $sub = Scope::Context->new->sub(1); # = Scope::Context->sub(1)
378 # $sub points to the context for the outer() sub.
384 my ($self, $frames) = @_;
387 if (Scalar::Util::blessed($self)) {
391 $cxt = Scope::Upper::UP(Scope::Upper::SUB());
394 $frames = 0 unless defined $frames;
396 $cxt = Scope::Upper::SUB($cxt);
397 $cxt = Scope::Upper::SUB(Scope::Upper::UP($cxt)) for 1 .. $frames;
404 my $eval_cxt = $cxt->eval;
405 my $eval_cxt = $cxt->eval($frames);
406 my $eval_cxt = Scope::Context->eval;
408 Returns a new L<Scope::Context> object pointing to the C<$frames>-th C<eval> scope above the scope pointed by the invocant.
410 This method can also be invoked as a class method, in which case it is equivalent to calling L</eval> on a L<Scope::Context> object for the current context.
412 If omitted, C<$frames> defaults to C<0>, which results in the closest eval enclosing the scope pointed by the invocant.
416 my $eval = Scope::Context->new->eval; # = Scope::Context->eval
417 # $eval points to the eval context.
424 my ($self, $frames) = @_;
427 if (Scalar::Util::blessed($self)) {
431 $cxt = Scope::Upper::UP(Scope::Upper::SUB());
434 $frames = 0 unless defined $frames;
436 $cxt = Scope::Upper::EVAL($cxt);
437 $cxt = Scope::Upper::EVAL(Scope::Upper::UP($cxt)) for 1 .. $frames;
446 Execute C<$code> when the scope pointed by the invocant ends.
448 See L<Scope::Upper/reap> for details.
453 my ($self, $code) = @_;
457 &Scope::Upper::reap($code, $self->cxt);
462 $cxt->localize($what, $value);
464 Localize the variable described by C<$what> to the value C<$value> when the control flow returns to the scope pointed by the invocant.
466 See L<Scope::Upper/localize> for details.
471 my ($self, $what, $value) = @_;
475 Scope::Upper::localize($what, $value, $self->cxt);
478 =head2 C<localize_elem>
480 $cxt->localize_elem($what, $key, $value);
482 Localize the element C<$key> of the variable C<$what> to the value C<$value> when the control flow returns to the scope pointed by the invocant.
484 See L<Scope::Upper/localize_elem> for details.
489 my ($self, $what, $key, $value) = @_;
493 Scope::Upper::localize_elem($what, $key, $value, $self->cxt);
496 =head2 C<localize_delete>
498 $cxt->localize_delete($what, $key);
500 Delete the element C<$key> from the variable C<$what> when the control flow returns to the scope pointed by the invocant.
502 See L<Scope::Upper/localize_delete> for details.
506 sub localize_delete {
507 my ($self, $what, $key) = @_;
511 Scope::Upper::localize_delete($what, $key, $self->cxt);
516 $cxt->unwind(@values);
518 Immediately returns the scalars listed in C<@values> from the closest subroutine enclosing the scope pointed by the invocant.
520 See L<Scope::Upper/unwind> for details.
529 Scope::Upper::unwind(@_ => $self->cxt);
534 $cxt->yield(@values);
536 Immediately returns the scalars listed in C<@values> from the scope pointed by the invocant, whatever it may be (except a substitution eval context).
538 See L<Scope::Upper/yield> for details.
547 Scope::Upper::yield(@_ => $self->cxt);
552 my @ret = $cxt->uplevel($code, @args);
554 Executes the code reference C<$code> with arguments C<@args> in the same setting as the closest subroutine enclosing the scope pointed by the invocant, then returns to the current scope the values returned by C<$code>.
556 See L<Scope::Upper/uplevel> for details.
566 &Scope::Upper::uplevel($code => @_ => $self->cxt);
571 L<Carp> (core module since perl 5), L<Scalar::Util> (since 5.7.3).
573 L<Scope::Upper> 0.21.
579 L<Continuation::Escape>.
583 Vincent Pit, C<< <perl at profvince.com> >>, L<http://www.profvince.com>.
585 You can contact me by mail or on C<irc.perl.org> (vincent).
589 Please report any bugs or feature requests to C<bug-scope-context at rt.cpan.org>, or through the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Scope-Context>.
590 I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
594 You can find documentation for this module with the perldoc command.
596 perldoc Scope::Context
598 =head1 COPYRIGHT & LICENSE
600 Copyright 2011,2012,2013 Vincent Pit, all rights reserved.
602 This program is free software; you can redistribute it and/or modify it
603 under the same terms as Perl itself.
607 1; # End of Scope::Context