in reply to "last expression" quiz

I don't understand how can it be at the same time defined, == 0, and eq "".

This is easy. The return value is the empty string !1 as bart says.

$ perl -le 'print "yes" if defined ""' yes $ perl -le 'print "yes" if 0 == ""' yes $ perl -le 'print "yes" if "" eq ""' yes

The bigger question you are asking—basically, why the empty string is returned—doesn't seem to have such a clear answer. This has come up recently in the discussion that followed Re^4: Unhappy returns. You'll find a closer look at the more general issue including how other statements are handled there. FWIW, I think it should probably be considered a bug. I'm pretty sure it isn't documented.

Which is exactly the same as the empty string only, uh, different It doesn't cause warnings where an empty string would.

Edit: Corrected "empty string" to !1 per bart's response below and added footnote.

-sauoq
"My two cents aren't worth a dime.";

Replies are listed 'Best First'.
Re^2: "last expression" quiz
by fxn (Sexton) on Oct 19, 2005 at 22:21 UTC

    Oh, yes, AND not issue a warning:

    % perl -wle 'print 1 if "" == 0' Argument "" isn't numeric in numeric eq (==) at -e line 1. 1
      A for loop typically returns nothing, whatever that means...

      Judging by your results on the warnings, or rather the lack of them, I think the subs return false, thus, !1. That is both equal to "" and numerically equal to 0 without a warning.

      Oh, and a 1 is allowed to be used as a statement without warning. Typical use for them is in a bodyless loop:

      1 while COND;
      as well as as the last statement in a required file/module. Hence that there's no warning for a bare 1;.

        Actually, a for loop does return something. Assuming it runs at least once, it will return an empty string, alias scalar false.

        There seems to be no particular reason for that behaviour.

        Makeshifts last the longest.

        Oh, and another thing: you can use either 0 or 1 as a constant in void context without getting a warning, but you can also use any string that starts with "ig", "ds", or "di", as Dominus famously demonstrated.

        Makeshifts last the longest.

        as well as as the last statement in a required file/module.

        Well, you can use whatever you want as the last statement of a required module without getting the "Useless use of a constant in void context" warning.

        -sauoq
        "My two cents aren't worth a dime.";
        
Re^2: "last expression" quiz
by fxn (Sexton) on Oct 20, 2005 at 09:27 UTC

    You see, you are wondering about some stuff and learn a lot by side effect. Thank you very much for your answers.

    With regard to the very "last expression", I guess we could conclude perlsub is not accurate there. It is true that some value is always returned, but in the subroutine

    sub foo { 1 for @_ }
    there are only TWO expressions, namely "1", and "@_". The "last expression" by definition should be one of them, but the return value is none of them.

    Does anybody disagree with that conclusion?

      Does anybody disagree with that conclusion?

      I certainly don't. An even better example:

      sub foo { 1 for 1 }
      Now there's only one expression which always evaluates to the same thing, 1, and yet the sub unintuitively returns !1. Certainly a patch is needed. Whether it should just be a doc patch to perlsub or different behavior should be forced, I don't know.

      -sauoq
      "My two cents aren't worth a dime.";
      
        Okay, I figured it was some peephole optimization thing. This is not what I would have predicted for deparse output, but it kind of makes sense.
        $ perl -MO=Deparse -e 'sub foo { 1 for 1 } foo' sub foo { foreach $_ (1) { '???'; } } foo ; -e syntax OK
        The '???' appears for other constants, with which it would generate "useless use of constant in void context" warnings. This warning is suppressed for a few common constants. So I guess the opcode optimizer just forgets WHAT constant was there.

        --
        [ e d @ h a l l e y . c c ]