in reply to Using ternary operator as lvalue in push

I've actually run into this problem before. Correct me if I'm wrong, but the code that isn't working for you is:

push $cond > 0 ? @a : @b , $elem;

I remember reading somewhere that the ternary binds more closely than the conditional. This means that the ternary operator sees only the 0, assumes it to be a false condition, and then reports @a back to the conditional statement. @a would then be evaluated in scalar context and compared to $code. No matter what the result, this eventually means that push will be getting a boolean value (which may be null) instead of an array to push into. To fix this, simply enclose the conditional statement in parentheses, as below. This forces the conditional to evaluate first, followed by the ternary, which then reports to push.

push ($cond > 0) ? @a : @b , $elem;

This is what has worked for me in the past. I'm currently on a handicapped (perl-less) machine, so I'm not able to test it. Someone please test and confirm.

Update: This explanation is completely wrong, and does not even work, as explained below. The problem is instead related to the prototyping in push. My deepest apologies. Next time I will wait to consult the texts before answering.

Replies are listed 'Best First'.
Re^2: Using ternary operator as lvalue in push
by ikegami (Patriarch) on Jul 31, 2007 at 16:37 UTC

    Youch, that's completely wrong.

    First of all, the basic idea is wrong. Relational operators (like >) have higher precedence than the conditional operator (?:), so attempting to raise the precendence of > using parens is a no-go. (See perlop.) *

    Furthermore, you actually made things worse by adding the parens because
    push ($cond > 0) ? @a : @b, $elem;
    is the same as
    push($cond > 0) ? @a : @b, $elem;
    is the same as
    (push($cond > 0)) ? @a : @b, $elem;
    which is quite wrong.

    Finally, even if done right, the parens don't help. Both
    push(($cond > 0) ? @a : @b, $elem);
    and
    push((($cond > 0) ? @a : @b), $elem);
    produce the same result as the OP.

    * — You might be thinking of the assignment operators rather than relational operators. Since the conditional operator (?:) has higher precedence than the assignment operators (like =), $cond ? $a = 1 : $b = 1; means ($cond ? $a = 1 : $b) = 1;.

Re^2: Using ternary operator as lvalue in push
by amarquis (Curate) on Jul 31, 2007 at 16:27 UTC

    I too am on a Perl-less machine, and don't have a lot of experience but here are my two cents:

    Won't the following:

    push ($cond > 0) ? @a : @b , $elem;

    Evaluate the greater than comparison, but then try to push the result before the ternary operator gets a hold of it? The ternary operator, I know, has pretty darn low precedence.