Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

B::Deparse fails to correctly deparse hash-derefs with conditional logic within #15102

Open
p5pRT opened this issue Dec 25, 2015 · 4 comments
Open

Comments

@p5pRT
Copy link

p5pRT commented Dec 25, 2015

Migrated from rt.perl.org#127026 (status was 'open')

Searchable as RT127026$

@p5pRT
Copy link
Author

p5pRT commented Dec 25, 2015

From @demerphq

It seems that a construct like

%{ delete $_{x} || {} }

is deparsed horribly incorrectly​:

$ perl -MO=Deparse -e'$x=sub{ scalar %{ delete $_{x} || {} } }; print $x->();'
$x = sub {
  scalar %{{} unless delete $_{'x'};};
}
;
print &$x();
-e syntax OK

This was originally a ticket against Data​::Dump​::Streamer which uses
B​::Deparse internally for serializing code refs.

See​:

https://rt.cpan.org/Ticket/Display.html?id=103543

Yves

--
perl -Mre=debug -e "/just|another|perl|hacker/"

@p5pRT
Copy link
Author

p5pRT commented Dec 25, 2015

From zefram@fysh.org

yves orton wrote​:

$ perl -MO=Deparse -e'$x=sub{ scalar %{ delete $_{x} || {} } }; print $x->();'
$x = sub {
scalar %{{} unless delete $_{'x'};};

This deparse isn't horribly incorrect. It's essentially correct​: an
oddity of the sigil+braces syntax is that the braced group is a code
block, within which statement syntax prevails, not expression syntax.

The strange thing is why the output isn't accepted by the parser.
The error message, "unmatched right curly bracket", looks incorrect,
and several minor variations on the input lead to it being accepted.
What's actually going on is that "%{{}" is interpreted as a reference to
the hash whose name is just an open brace character. This is rather
insane; "%{" is never interpreted that way, and we don't have any
meaningful variables with such names. We might want to change that
behaviour, but it is rather long-standing.

B​::Deparse could work around this by adding a semicolon after the first
open brace. To be nice we'd really want it to only do that if the code
to go in the braced block starts with the problematic "{}".

-zefram

@p5pRT
Copy link
Author

p5pRT commented Dec 25, 2015

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Dec 25, 2015

From @demerphq

On 25 December 2015 at 05​:06, Zefram <zefram@​fysh.org> wrote​:

yves orton wrote​:

$ perl -MO=Deparse -e'$x=sub{ scalar %{ delete $_{x} || {} } }; print $x->();'
$x = sub {
scalar %{{} unless delete $_{'x'};};

This deparse isn't horribly incorrect. It's essentially correct​: an
oddity of the sigil+braces syntax is that the braced group is a code
block, within which statement syntax prevails, not expression syntax.

WOAH. Talk about surprising​:

perl -e'$x=sub{ scalar %{; {} unless delete $_{x}; }; }; print $x->();'

I bet prior to this mail you were one of a very very very small group
who knew that. I am literally stunned.

The strange thing is why the output isn't accepted by the parser.
The error message, "unmatched right curly bracket", looks incorrect,
and several minor variations on the input lead to it being accepted.
What's actually going on is that "%{{}" is interpreted as a reference to
the hash whose name is just an open brace character. This is rather
insane; "%{" is never interpreted that way, and we don't have any
meaningful variables with such names. We might want to change that
behaviour, but it is rather long-standing.

I see. I will leave that to you and those who knew about this subtlety
to decide.

B​::Deparse could work around this by adding a semicolon after the first
open brace. To be nice we'd really want it to only do that if the code
to go in the braced block starts with the problematic "{}".

Nod. I get you. I think I could probably fix DDS to do this
automagically, so that it works until B​::Deparse gets fixed.

Cheers,
Yves

--
perl -Mre=debug -e "/just|another|perl|hacker/"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants