use Test::More;
-plan tests => 23 * ($^P ? 4 : 5) + ($^P ? 1 : 2) + 7 + 15 * 2;
+plan tests => 1 + 23 * ($^P ? 4 : 5) + ($^P ? 1 : 3) + 7 + (32 + 7);
use Scope::Upper qw<:words>;
# Tests with hardcoded values are for internal use only and doesn't imply any
# kind of future compatibility on what the words should actually return.
+our $got_warn;
+my $warn_catcher = sub {
+ my $file = __FILE__;
+ ++$got_warn if $_[0] =~ /^Cannot target a scope outside of the current stack at \Q$file\E line \d+\.$/;
+ return;
+};
+my $old_sig_warn;
+
my $top = HERE;
-is $top, 0, 'main : here' unless $^P;
-is TOP, $top, 'main : top';
-is UP, $top, 'main : up';
-is SUB, undef, 'main : sub';
-is EVAL, undef, 'main : eval';
+is $top, 0, 'main : here' unless $^P;
+is TOP, $top, 'main : top';
+$old_sig_warn = $SIG{__WARN__};
+local ($SIG{__WARN__}, $got_warn) = $warn_catcher;
+is UP, $top, 'main : up';
+local $SIG{__WARN__} = $old_sig_warn;
+is $got_warn, 1, 'main : up warns';
+is SUB, undef, 'main : sub';
+is EVAL, undef, 'main : eval';
{
my $desc = '{ 1 }';
for (my $i = 0; $i < 1; ++$i) {
my $desc = 'for (;;) { 1 }';
- is HERE, 2, "$desc : here" unless $^P;
+ is HERE, 1, "$desc : here" unless $^P;
is TOP, $top, "$desc : top";
is UP, $top, "$desc : up";
is SUB, undef, "$desc : sub";
my @list = (1);
while (my $thing = shift @list) {
my $desc = 'while (my $thing = ...) { 2 }';
- is HERE, "$]" <= 5.008_008 ? 1 : 2, "$desc : here" unless $^P;
- is TOP, $top, "$desc : top";
- is UP, $top, "$desc : up";
- is SUB, undef, "$desc : sub";
- is EVAL, undef, "$desc : eval";
+ is HERE, 1, "$desc : here" unless $^P;
+ is TOP, $top, "$desc : top";
+ is UP, $top, "$desc : up";
+ is SUB, undef, "$desc : sub";
+ is EVAL, undef, "$desc : eval";
}
do {
my $var = 'a';
$var =~ s{.}{
my $desc = 'subst';
- is HERE, 2, "$desc : here" unless $^P;
+ is HERE, 1, "$desc : here" unless $^P;
is TOP, $top, "$desc : top";
is UP, $top, "$desc : up";
is SUB, undef, "$desc : sub";
$var = 'a';
$var =~ s{.}{do { UP }}e;
-is $var, 2, 'subst : real block' unless $^P;
+is $var, 1, 'subst : do block optimized away' unless $^P;
+
+$var = 'a';
+$var =~ s{.}{do { my $x; UP }}e;
+is $var, 1, 'subst : do block preserved' unless $^P;
SKIP: {
skip 'Perl 5.10 required to test given/when' => 4 * ($^P ? 4 : 5)
if "$]" < 5.010;
eval <<'TEST_GIVEN';
+ BEGIN {
+ if ("$]" >= 5.017_011) {
+ require warnings;
+ warnings->unimport('experimental::smartmatch');
+ }
+ }
use feature 'switch';
my $desc = 'given';
my $base = HERE;
given (1) {
- is HERE, $base + 2, "$desc : here" unless $^P;
+ is HERE, $base + 1, "$desc : here" unless $^P;
is TOP, $top, "$desc : top";
is UP, $base, "$desc : up";
is SUB, undef, "$desc : sub";
diag $@ if $@;
eval <<'TEST_GIVEN_WHEN';
+ BEGIN {
+ if ("$]" >= 5.017_011) {
+ require warnings;
+ warnings->unimport('experimental::smartmatch');
+ }
+ }
use feature 'switch';
my $desc = 'when in given';
my $base = HERE;
given (1) {
my $given = HERE;
when (1) {
- is HERE, $base + 4, "$desc : here" unless $^P;
+ is HERE, $base + 3, "$desc : here" unless $^P;
is TOP, $top, "$desc : top";
is UP, $given, "$desc : up";
is SUB, undef, "$desc : sub";
diag $@ if $@;
eval <<'TEST_GIVEN_DEFAULT';
+ BEGIN {
+ if ("$]" >= 5.017_011) {
+ require warnings;
+ warnings->unimport('experimental::smartmatch');
+ }
+ }
use feature 'switch';
my $desc = 'default in given';
my $base = HERE;
given (1) {
my $given = HERE;
default {
- is HERE, $base + 4, "$desc : here" unless $^P;
+ is HERE, $base + 3, "$desc : here" unless $^P;
is TOP, $top, "$desc : top";
is UP, $given, "$desc : up";
is SUB, undef, "$desc : sub";
diag $@ if $@;
eval <<'TEST_FOR_WHEN';
+ BEGIN {
+ if ("$]" >= 5.017_011) {
+ require warnings;
+ warnings->unimport('experimental::smartmatch');
+ }
+ }
use feature 'switch';
my $desc = 'when in for';
my $base = HERE;
for (1) {
my $loop = HERE;
when (1) {
- is HERE, $base + 3, "$desc : here" unless $^P;
+ is HERE, $base + 2, "$desc : here" unless $^P;
is TOP, $top, "$desc : top";
is UP, $loop, "$desc : up";
is SUB, undef, "$desc : sub";
is SCOPE, $block, 'block : scope';
is SCOPE(0), $block, 'block : scope 0';
is SCOPE(1), $top, 'block : scope 1';
+ $old_sig_warn = $SIG{__WARN__};
+ local ($SIG{__WARN__}, $got_warn) = $warn_catcher;
+ is SCOPE(2), $top, 'block : scope 2';
+ is $got_warn, 1, 'block : scope 2 warns';
+ local $got_warn;
is CALLER, $top, 'block : caller';
+ is $got_warn, 1, 'block : caller warns';
+ local $got_warn;
is CALLER(0), $top, 'block : caller 0';
+ is $got_warn, 1, 'block : caller 0 warns';
+ local $got_warn;
is CALLER(1), $top, 'block : caller 1';
+ is $got_warn, 1, 'block : caller 1 warns';
+ local $SIG{__WARN__} = $old_sig_warn;
sub {
my $sub = HERE;
is SCOPE, $sub, 'block sub : scope';
is SCOPE(0), $sub, 'block sub : scope 0';
is SCOPE(1), $block, 'block sub : scope 1';
+ is SCOPE(2), $top, 'block sub : scope 2';
is CALLER, $sub, 'block sub : caller';
is CALLER(0), $sub, 'block sub : caller 0';
+ $old_sig_warn = $SIG{__WARN__};
+ local ($SIG{__WARN__}, $got_warn) = $warn_catcher;
is CALLER(1), $top, 'block sub : caller 1';
+ local $SIG{__WARN__} = $old_sig_warn;
+ is $got_warn, 1, 'block sub : caller 1 warns';
for (1) {
my $loop = HERE;
is SCOPE, $loop, 'block sub for : scope';
is SCOPE(0), $loop, 'block sub for : scope 0';
is SCOPE(1), $sub, 'block sub for : scope 1';
is SCOPE(2), $block, 'block sub for : scope 2';
+ is SCOPE(3), $top, 'block sub for : scope 3';
is CALLER, $sub, 'block sub for : caller';
is CALLER(0), $sub, 'block sub for : caller 0';
+ $old_sig_warn = $SIG{__WARN__};
+ local ($SIG{__WARN__}, $got_warn) = $warn_catcher;
is CALLER(1), $top, 'block sub for : caller 1';
- is CALLER(2), $top, 'block sub for : caller 2';
+ local $SIG{__WARN__} = $old_sig_warn;
+ is $got_warn, 1, 'block sub for : caller 1 warns';
eval {
my $eval = HERE;
is SCOPE, $eval, 'block sub for eval : scope';
is SCOPE(1), $loop, 'block sub for eval : scope 1';
is SCOPE(2), $sub, 'block sub for eval : scope 2';
is SCOPE(3), $block, 'block sub for eval : scope 3';
+ is SCOPE(4), $top, 'block sub for eval : scope 4';
is CALLER, $eval, 'block sub for eval : caller';
is CALLER(0), $eval, 'block sub for eval : caller 0';
is CALLER(1), $sub, 'block sub for eval : caller 1';
+ $old_sig_warn = $SIG{__WARN__};
+ local ($SIG{__WARN__}, $got_warn) = $warn_catcher;
is CALLER(2), $top, 'block sub for eval : caller 2';
- is CALLER(3), $top, 'block sub for eval : caller 3';
+ local $SIG{__WARN__} = $old_sig_warn;
+ is $got_warn, 1, 'block sub for eval : caller 2 warns';
}
}
}->();