diff options
author | Father Chrysostomos <sprout@cpan.org> | 2011-12-21 08:17:01 -0800 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2011-12-21 10:37:51 -0800 |
commit | be6cf5cf0a864ce5ef586bff8ef592ed0485d201 (patch) | |
tree | b08367dba1946f80aa99c3c7454b812be874bbdf | |
parent | 86c08a2ca2546ef08513c65dabf686423cade2f3 (diff) | |
download | perl-be6cf5cf0a864ce5ef586bff8ef592ed0485d201.tar.gz |
Deparse "string"->[0] correctly
"foo"->[0] and $foo[0] compile down to the same thing. B::Deparse was
assuming that an rv2gv with a gv kid would have to be $foo[0] syntax,
so it didn’t take things like '!@T#$'->[0] into account.
This commit only fixes aelemfast. It is related to b89b7257.
-rw-r--r-- | dist/B-Deparse/Deparse.pm | 34 | ||||
-rw-r--r-- | dist/B-Deparse/t/deparse.t | 12 |
2 files changed, 34 insertions, 12 deletions
diff --git a/dist/B-Deparse/Deparse.pm b/dist/B-Deparse/Deparse.pm index 6a4d8cb78a..d99080aa03 100644 --- a/dist/B-Deparse/Deparse.pm +++ b/dist/B-Deparse/Deparse.pm @@ -1304,6 +1304,23 @@ sub stash_variable { return "$prefix$name"; } +# Return just the name, without the prefix. It may be returned as a quoted +# string. The second return value is a boolean indicating that. +sub stash_variable_name { + my($self, $prefix, $gv) = @_; + my $name = $self->gv_name($gv, 1); + $name = $self->{'curstash'}.'::'. $name + if $prefix and $self->lex_in_scope("$prefix$name"); + if ($name =~ /^(?:\S|(?!\d)[\ca-\cz]?(?:\w|::)*|\d+)\z/) { + $name =~ s/^([\ca-\cz])/'^'.($1|'@')/e; + $name =~ /^(\^..|{)/ and $name = "{$name}"; + return $name, 0; # not quoted + } + else { + single_delim("q", "'", $name), 1; + } +} + sub lex_in_scope { my ($self, $name) = @_; $self->populate_curcvlex() if !defined $self->{'curcvlex'}; @@ -2373,14 +2390,9 @@ sub pp_dorassign { logassignop(@_, "//=") } sub rv2gv_or_string { my($self,$op) = @_; if ($op->name eq "gv") { # could be open("open") or open("###") - my $name = $self->gv_name($self->gv_or_padgv($op), 1); - if ($name =~ /^(?:\S|(?!\d)[\ca-\cz]?\w*|\d+)\z/) { - $name =~ s/^([\ca-\cz])/'^'.($1|'@')/e; - $name =~ /^(\^..|{)/ ? "*{$name}" : "*$name"; - } - else { - single_delim("q", "'", $name); - } + my($name,$quoted) = + $self->stash_variable_name(undef,$self->gv_or_padgv($op)); + $quoted ? $name : "*$name"; } else { $self->deparse($op, 6); @@ -3050,10 +3062,8 @@ sub pp_aelemfast { return $self->pp_aelemfast_lex(@_) if ($op->flags & OPf_SPECIAL); my $gv = $self->gv_or_padgv($op); - my $name = $self->gv_name($gv); - $name = $self->{'curstash'}."::$name" - if $name !~ /::/ && $self->lex_in_scope('@'.$name); - $name = '$' . $name; + my($name,$quoted) = $self->stash_variable_name('@',$gv); + $name = $quoted ? "$name->" : '$' . $name; return $name . "[" . ($op->private + $self->{'arybase'}) . "]"; } diff --git a/dist/B-Deparse/t/deparse.t b/dist/B-Deparse/t/deparse.t index be9cbb6d29..2baef66027 100644 --- a/dist/B-Deparse/t/deparse.t +++ b/dist/B-Deparse/t/deparse.t @@ -902,6 +902,18 @@ open '####'; open '^A'; open *^A; #### +# "string"->[] ->{} +no strict 'vars'; +() = 'open'->[0]; #aelemfast +() = '####'->[0]; +() = '^A'->[0]; +() = "\ca"->[0]; +>>>> +() = $open[0]; +() = '####'->[0]; +() = '^A'->[0]; +() = $^A[0]; +#### # [perl #74740] -(f()) vs -f() $_ = -(f()); #### |