X-Git-Url: http://git.vpit.fr/?p=perl%2Fmodules%2FScope-Context.git;a=blobdiff_plain;f=lib%2FScope%2FContext.pm;h=6658c3cfe8596208bdb09fd4ccca799230192cbf;hp=0bbfd91cc3e15824d414e09e9d7fe6303bdc52b5;hb=3c4dd9fbf7894245f46e02300a54df2971e12a27;hpb=4d0d929cc4f8e8f7ad6a2a4bd9caa2ab55b0259a diff --git a/lib/Scope/Context.pm b/lib/Scope/Context.pm index 0bbfd91..6658c3c 100644 --- a/lib/Scope/Context.pm +++ b/lib/Scope/Context.pm @@ -16,11 +16,11 @@ Scope::Context - Object-oriented interface for inspecting or acting upon upper s =head1 VERSION -Version 0.01 +Version 0.02 =cut -our $VERSION = '0.01'; +our $VERSION = '0.02'; =head1 SYNOPSIS @@ -29,32 +29,33 @@ our $VERSION = '0.01'; for (1 .. 5) { sub { eval { - # Create Scope::Context objects for different upper frames. - my ($block, $sub, $eval, $loop); + # Create Scope::Context objects for different upper frames : + my ($block, $eval, $sub, $loop); { $block = Scope::Context->new; - $sub = $block->sub; # = $block->up - $eval = $block->eval; # = $block->up(2) - $loop = $eval->up; # = $block->up(3) + $eval = $block->eval; # == $block->up + $sub = $block->sub; # == $block->up(2) + $loop = $sub->up; # == $block->up(3) } eval { - # This will throw an exception, since $block has expired. + # This throws an exception, since $block has expired : $block->localize('$x' => 1); }; - # This prints "hello" when the eval block above ends. + # This will print "hello" when the current eval block ends : $eval->reap(sub { print "hello\n" }); - # Ignore $SIG{__DIE__} just for the loop body. - $loop->localize_delete('%SIG', '__DIE__'); + # Ignore warnings just for the loop body : + $loop->localize_elem('%SIG', __WARN__ => sub { }); - # Execute the callback as if it ran in place of the sub. + # Execute the callback as if it ran in place of the sub : my @values = $sub->uplevel(sub { return @_, 2; }, 1); + # @values now contains (1, 2). - # Immediately return (1, 2, 3) from the sub, bypassing the eval. + # Immediately return (1, 2, 3) from the sub, bypassing the eval : $sub->unwind(@values, 3); # Not reached. @@ -63,10 +64,13 @@ our $VERSION = '0.01'; # Not reached. }->(); - # unwind() returns here. "hello\n" was printed, and now - # $SIG{__DIE__} is undefined. + # unwind() returns here. "hello\n" was printed, and now warnings are + # ignored. } + # $SIG{__WARN__} has been restored to its original value, warnings are no + # longer ignored. + =head1 DESCRIPTION This class provides an object-oriented interface to L's functionalities. @@ -194,6 +198,110 @@ sub assert_valid { 1; } +=head2 C + + $cxt->package; + +Returns the namespace in use when the scope denoted by the invocant begins. + +=head2 C + + $cxt->file; + +Returns the name of the file where the scope denoted by the invocant belongs to. + +=head2 C + + $cxt->line; + +Returns the line number where the scope denoted by the invocant begins. + +=head2 C + + $cxt->sub_name; + +Returns the name of the subroutine called for this context, or C if this is not a subroutine context. + +=head2 C + + $cxt->sub_has_args; + +Returns a boolean indicating whether a new instance of C<@_> was set up for this context, or C if this is not a subroutine context. + +=head2 C + + $cxt->gimme; + +Returns the context (in the sense of L) in which the scope denoted by the invocant is executed. + +=head2 C + + $cxt->eval_text; + +Returns the contents of the string being compiled for this context, or C if this is not an eval context. + +=head2 C + + $cxt->is_require; + +Returns a boolean indicating whether this eval context was created by C, or C if this is not an eval context. + +=head2 C + + $cxt->hints_bits; + +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. + +=head2 C + + $cxt->warnings_bits; + +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. + +=head2 C + + $cxt->hints_hash; + +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. +This method is available only on perl 5.10 and greater. + +=cut + +BEGIN { + my %infos = ( + package => 0, + file => 1, + line => 2, + sub_name => 3, + sub_has_args => 4, + gimme => 5, + eval_text => 6, + is_require => 7, + hints_bits => 8, + warnings_bits => 9, + (hints_hash => 10) x ("$]" >= 5.010), + ); + + for my $name (sort { $infos{$a} <=> $infos{$b} } keys %infos) { + my $idx = $infos{$name}; + local $@; + eval <<" TEMPLATE"; + sub $name { + my \$self = shift; + + \$self->assert_valid; + + my \$info = \$self->{info}; + \$info = \$self->{info} = [ Scope::Upper::context_info(\$self->cxt) ] + unless \$info; + + return \$info->[$idx]; + } + TEMPLATE + die $@ if $@; + } +} + =head2 C my $want = $cxt->want; @@ -257,7 +365,7 @@ sub up { my $sub_cxt = $cxt->sub($frames); my $sub_cxt = Scope::Context->sub; -Returns a new L object pointing to the C<$frames>-th subroutine scope above the scope pointed by the invocant. +Returns a new L object pointing to the C<$frames + 1>-th subroutine scope above the scope pointed by the invocant. This method can also be invoked as a class method, in which case it is equivalent to calling L on a L object for the current context. @@ -301,7 +409,7 @@ sub sub { my $eval_cxt = $cxt->eval($frames); my $eval_cxt = Scope::Context->eval; -Returns a new L object pointing to the C<$frames>-th C scope above the scope pointed by the invocant. +Returns a new L object pointing to the C<$frames + 1>-th C scope above the scope pointed by the invocant. This method can also be invoked as a class method, in which case it is equivalent to calling L on a L object for the current context. @@ -493,7 +601,7 @@ You can find documentation for this module with the perldoc command. =head1 COPYRIGHT & LICENSE -Copyright 2011,2012 Vincent Pit, all rights reserved. +Copyright 2011,2012,2013,2015 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.