develooper Front page | perl.perl5.porters | Postings from October 2014

Re: Unexpected deparse output

Thread Previous
Father Chrysostomos
October 8, 2014 19:35
Re: Unexpected deparse output
Message ID:
Peter Rabbitson wrote:
> I get the output
> use constant ('foo', 0);
> if ((int(rand 2) + 1) % 2) {
>      warn 'foo';
> }
> else {
>      '???';
> }
> -e syntax OK
> I would have expected the elsif to disappear entirely. Instead it is
> converted to this weird empty-else. Is the SCOPE op still there or is
> this just Deparse being silly?

A bit of both.  No, there is no else thingy there to be executed, but
B::Deparse intentionally emits constants that have been optimised
away.  And that is the only way to dump such a constant after 'if'.

That whole if-block is somewhat equivalent to

    int... ? warn "foo" : 0 && warn "bar"

if you ignore scopes.  So the && on the rhs gets optimised to 0
and you have:

    int... ? warn "foo" : 0

Then void context is applied, which turns the 0 into a null op.  Null
ops get removed from the execution chain.

If you put the entire block in a do-block that is in scalar context,
you get output like this:

use constant ('foo', 0);
$x = do {
    if ((int(rand 2) + 1) % 2) {
        warn 'foo';
    else {

In this case, B::Deparse is still conjuring up the else-block out of
thin air (there is no block in the compiled code; just a constant).
But there is no other way to emit it.

Looking further, I see that empty elses (I mean actual empty elses in
the source code) are not optimised away, though they could be....

Thread Previous Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About