diff options
author | Father Chrysostomos <sprout@cpan.org> | 2014-12-11 16:21:27 -0800 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2014-12-11 17:45:38 -0800 |
commit | d98ae4a6b04a455a18f2704a66dbe21fb352baf8 (patch) | |
tree | 673670fd544bf637c2b80617dd4175151ce68798 /lib | |
parent | 8f074d66877960697c1c72433068824e05aa0e9d (diff) | |
download | perl-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.pm | 7 | ||||
-rw-r--r-- | lib/B/Deparse.t | 7 |
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'; |