in reply to Re: Confused by Perl ternary operator
in thread Confused by Perl ternary operator

In this case, for arcane reasons, $param3 = @_ ? "Shift" : shift works as-is but is execution-order unsafe and if the expression were included in some other larger expression, could be quite a problem.

$param3 = @_ ? "Shift" : $_[0]; shift;

The preceding example would be the safe way to write it.

Replies are listed 'Best First'.
Re^3: Confused by Perl ternary operator
by ysth (Canon) on Aug 23, 2004 at 23:36 UTC
    How is that execution-order unsafe? ?:'s first operand has to be evaluated before either the second or third.

    After writing the above, I checked perlop.pod, and technically you are correct. ?: isn't documented as short-circuiting, so perl potentially could evaluate the 2nd and 3rd operands before testing the first one. However, I believe that it is intended to short-circuit and will submit a patch to the doc.

    As an interesting side note, structures with else or elsif are implemented using condexpr (the ?: operator). That is,

    if (foo) { bar } else { baz }
    is identical to
    foo ? do { bar } : do { baz }
    so the short-circuiting of ?: is pretty guaranteed.

      I was thinking that someone might use that expression that reads and writes to @_ inside another expression that depends on whether @_ has already been fetched or altered. ?: isn't just if/else, its an expression which can be used inside other expressions.

      $join = ( @_ ? "Argument, the first" : shift ) . ( @_ ? "Argument, the second" : shift );