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

Re: Unexpected deparse output

Thread Previous
From:
Father Chrysostomos
Date:
October 8, 2014 19:35
Subject:
Re: Unexpected deparse output
Message ID:
20141008193501.9348.qmail@lists-nntp.develooper.com
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 {
        0;
    }
};

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


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About