summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2014-12-11 16:21:27 -0800
committerFather Chrysostomos <sprout@cpan.org>2014-12-11 17:45:38 -0800
commitd98ae4a6b04a455a18f2704a66dbe21fb352baf8 (patch)
tree673670fd544bf637c2b80617dd4175151ce68798 /lib
parent8f074d66877960697c1c72433068824e05aa0e9d (diff)
downloadperl-d98ae4a6b04a455a18f2704a66dbe21fb352baf8.tar.gz
Deparse: Emit package before use
Prior to commit c310a5abf, ‘use’ statements in packages other than main were emitted as BEGIN blocks, because the code that decides whether BEGIN is actually ‘use’ was looking for "BEGIN", not "Foo::BEGIN": $ perl -MO=Deparse -e 'package foo; use overload' package foo; sub BEGIN { require overload; do { 'overload'->import }; } -e syntax OK That changed inadvertently in v5.21.6-397-gc310a5a (Don’t deparse BEGIN blocks as __ANON__), because B::Deparse now remembers the name "BEGIN" for all BEGIN blocks, regardless of package. That caused an existing bug to occur more often: $ perl5.20.1 -MO=Deparse -e 'package foo; die; package main; use overload qr=>sub{die}' package foo; die; use overload ('qr', sub { die; } ); -e syntax OK Notice that there is no ‘package main’ anywhere. (Just before c310a5a the ‘package main’ would have appeared inside the anonymous sub.) In c310a5a this started applying to packages other than main, with a ‘use’ statement just after the package declaration. This commit fixes that by returning the ‘use’ statement only *after* doing the check to see whether there was a package declaration, and by including the package declaration in what is returned.
Diffstat (limited to 'lib')
-rw-r--r--lib/B/Deparse.pm7
-rw-r--r--lib/B/Deparse.t7
2 files changed, 11 insertions, 3 deletions
diff --git a/lib/B/Deparse.pm b/lib/B/Deparse.pm
index a24d98f154..0535262ef6 100644
--- a/lib/B/Deparse.pm
+++ b/lib/B/Deparse.pm
@@ -567,12 +567,12 @@ sub next_todo {
. $self->deparse_format($ent->[1]). "\n";
} else {
$self->{'subs_declared'}{$name} = 1;
+ my $use_dec;
if ($name eq "BEGIN") {
- my $use_dec = $self->begin_is_use($cv);
+ $use_dec = $self->begin_is_use($cv);
if (defined ($use_dec) and $self->{'expand'} < 5) {
return () if 0 == length($use_dec);
$use_dec =~ s/^(use|no)\b/$self->keyword($1)/e;
- return $use_dec;
}
}
my $l = '';
@@ -591,6 +591,9 @@ sub next_todo {
$self->{'curstash'} = $stash;
}
}
+ if ($use_dec) {
+ return "$p$l$use_dec";
+ }
if ( $name !~ /::/ and $self->lex_in_scope("&$name")
|| $self->lex_in_scope("&$name", 1) )
{
diff --git a/lib/B/Deparse.t b/lib/B/Deparse.t
index de05b611f0..69cba1db28 100644
--- a/lib/B/Deparse.t
+++ b/lib/B/Deparse.t
@@ -13,7 +13,7 @@ BEGIN {
use warnings;
use strict;
-my $tests = 38; # not counting those in the __DATA__ section
+my $tests = 39; # not counting those in the __DATA__ section
use B::Deparse;
my $deparse = B::Deparse->new();
@@ -454,6 +454,11 @@ like runperl(stderr => 1, switches => [ '-MO=-qq,Deparse', $path ],
'BEGIN block inside predeclared sub';
like runperl(stderr => 1, switches => [ '-MO=-qq,Deparse', $path ],
+ prog => 'package foo; use overload qr=>sub{}'),
+ qr/package foo;\s*use overload/,
+ 'package, then use';
+
+like runperl(stderr => 1, switches => [ '-MO=-qq,Deparse', $path ],
prog => 'use feature lexical_subs=>; my sub f;sub main::f{}'),
qr/^sub main::f \{/m,
'sub decl when lex sub is in scope';