From: Vincent Pit Date: Fri, 8 Feb 2013 16:19:49 +0000 (-0200) Subject: Implement context_info() accessors X-Git-Tag: v0.02~1 X-Git-Url: http://git.vpit.fr/?a=commitdiff_plain;h=f4699824df48f41d756111418704fca0d6d4d89e;p=perl%2Fmodules%2FScope-Context.git Implement context_info() accessors --- diff --git a/MANIFEST b/MANIFEST index 63ed67e..d8cad15 100644 --- a/MANIFEST +++ b/MANIFEST @@ -13,6 +13,7 @@ t/11-target.t t/12-actions.t t/13-valid.t t/14-cmp.t +t/15-info.t t/91-pod.t t/92-pod-coverage.t t/93-pod-spelling.t diff --git a/lib/Scope/Context.pm b/lib/Scope/Context.pm index 8fafca8..aa422e1 100644 --- a/lib/Scope/Context.pm +++ b/lib/Scope/Context.pm @@ -194,6 +194,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; diff --git a/t/02-can.t b/t/02-can.t index 5af4e46..595aaac 100644 --- a/t/02-can.t +++ b/t/02-can.t @@ -9,13 +9,23 @@ my @methods = qw< new here cxt uid is_valid assert_valid + + package file line + sub_name sub_has_args + gimme + eval_text is_require + hints_bits warnings_bits + want up sub eval + reap localize localize_elem localize_delete unwind yield uplevel >; +push @methods, 'hints_hash' if "$]" >= 5.010; + plan tests => scalar(@methods); require Scope::Context; diff --git a/t/15-info.t b/t/15-info.t new file mode 100644 index 0000000..8c01137 --- /dev/null +++ b/t/15-info.t @@ -0,0 +1,61 @@ +#!perl -T + +use strict; +use warnings; + +use Test::More tests => 5 + 2 + 3 + 2; + +use Scope::Context; + +{ + package Scope::Context::TestA; + { + my $line = __LINE__; + package Scope::Context::TestB; + my $cxt = Scope::Context->new; + package Scope::Context::TestC; + ::is $cxt->package, 'Scope::Context::TestA'; + ::is $cxt->file, __FILE__; + ::is $cxt->line, $line; + ::is $cxt->sub_name, undef; + ::is $cxt->eval_text, undef; + } +} + +sub flurbz { + my $cxt = Scope::Context->new; + [ $cxt->sub_name, $cxt->sub_has_args ] +} + +{ + my $info = flurbz(); + is($info->[0], 'main::flurbz'); + is($info->[1], !!1); +} + +{ + { + is(Scope::Context->new->gimme, undef, 'gimme in void context'); + } + my $s = do { + is(Scope::Context->new->gimme, !!'', 'gimme in scalar context'); + }; + my @a = do { + is(Scope::Context->new->gimme, !!1, 'gimme in list context'); + } +} + +{ + my $src = <<' SRC'; + my $cxt = Scope::Context->new; + [ $cxt->eval_text, $cxt->is_require ]; + SRC + my $info = do { + local $@; + eval $src; + }; + my $eval_text = $info->[0]; + s/[\s;]*$//g for $eval_text, $src; + is $eval_text, $src, 'eval_text in eval'; + is $info->[1], !!'', 'is_require in eval'; +}