Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Mixing OR with conditional operator

by jockel (Beadle)
on Nov 19, 2017 at 10:12 UTC ( [id://1203767]=perlquestion: print w/replies, xml ) Need Help??

jockel has asked for the wisdom of the Perl Monks concerning the following question:

Hi

Can someone please explain this behavior. I was surprised with result of the following code. (And please help me come up with a better Title for this question)

I think the variable $test should be set to $val1 (1) but instead it gets set to $val2 (undef)

#/usr/bin/perl use strict; my $test; $test = 1 || (undef && undef != 0) ? undef : 0; print "test = $test\n";
OUTPUT: test =
-----BEGIN PERL GEEK CODE BLOCK----- Version: 0.01 P++>*$c--->---P6 > R >++++$M+>+++$O+++>+++$MA->+++$E > PU->++BD->-C+>+$D+>+$S->+++X >+WP >+++MO!PP n?CO--PO!>!(!)o?G!A--OLC--OLCC--OLJ--Ee !Ev-Eon-uL++>*uB!uS!uH-uo!w->!m+ ------END PERL GEEK CODE BLOCK------

Replies are listed 'Best First'.
Re: Mixing OR with conditional operator
by choroba (Cardinal) on Nov 19, 2017 at 10:28 UTC
    It's a precedence problem.

    B::Deparse with the -p option can show you how Perl understands expressions. Unfortunately, the expression contains only constants, so it's evaluated at compile time, so the result isn't helpful:

    $ perl -MO=Deparse,-p 1.pl use strict; my($test); ($test = (undef)); print("test = $test\n"); 1.pl syntax OK

    You need to introduce variables to postpone the evaluation to runtime to get a more enlightening answer:

    #! /usr/bin/perl use warnings; use strict; my $test; my $undef; my $true = 1; my $zero = 0; $test = $true || ($undef && $undef != $zero) ? $undef : $zero; print "test = $test\n";

    And, voilą:

    use strict; my($test); my($undef); (my $true = 1); (my $zero = 0); ($test = (($true || ($undef && ($undef != $zero))) ? $undef : $zero)); print("test = $test\n"); 1.pl syntax OK

    Nicely indented:

    $test = ( ( $true || ( $undef && ( $undef != $zero ) ) ) ? $undef : $zero )

    $true || ... returns 1, so the "then" part of the ternary is returned, i.e. $undef.

    Maybe you wanted

    $test = $true || ($undef && $undef != $zero ? $undef : $zero);

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,

      Choroba,

      I have variables in my real code, I just thought I would simplify it as much as possible.

      Actually I first wrote an example just like your last example. But I didn't think my 'simplification' would actually change the whole behavior!

      OT: The current "Voting Booth"-question "In order to be able to say "I know Perl", you must have:", with the leading answer "One can never truly know perl", are totally correct ;-)

      Edit: And yes, your last one liner code-example, fixes the issue and I will adopt that syntax!

      Thank you!

      -----BEGIN PERL GEEK CODE BLOCK----- Version: 0.01 P++>*$c--->---P6 > R >++++$M+>+++$O+++>+++$MA->+++$E > PU->++BD->-C+>+$D+>+$S->+++X >+WP >+++MO!PP n?CO--PO!>!(!)o?G!A--OLC--OLCC--OLJ--Ee !Ev-Eon-uL++>*uB!uS!uH-uo!w->!m+ ------END PERL GEEK CODE BLOCK------
        > One can never truly know perl

        This problem is not Perl specific, you need to respect precedence in all languages.*

        Just try to do the same expression in JS or C ...

        Cheers Rolf
        (addicted to the Perl Programming Language and ☆☆☆☆ :)
        Je suis Charlie!

        update

        *) correction, most not all. You might enjoy Lisp or Assembler.

Re: Mixing OR with conditional operator
by BrowserUk (Patriarch) on Nov 19, 2017 at 10:21 UTC

    Try adding 'use warnings'. ( Use of uninitialized value in numeric ne (!=) )


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". The enemy of (IT) success is complexity.
    In the absence of evidence, opinion is indistinguishable from prejudice. Suck that fhit

      Hmm.

      I get no warning for row 5, only for row 7.

      Use of uninitialized value $test in concatenation (.) or string at /tmp/test2.pl line 7.

      Still, shouldn't the '1' before the OR evaluate first, and just skip everything after the OR?

      -----BEGIN PERL GEEK CODE BLOCK----- Version: 0.01 P++>*$c--->---P6 > R >++++$M+>+++$O+++>+++$MA->+++$E > PU->++BD->-C+>+$D+>+$S->+++X >+WP >+++MO!PP n?CO--PO!>!(!)o?G!A--OLC--OLCC--OLJ--Ee !Ev-Eon-uL++>*uB!uS!uH-uo!w->!m+ ------END PERL GEEK CODE BLOCK------
Re: Mixing OR with conditional operator
by Anonymous Monk on Nov 20, 2017 at 13:46 UTC
    Speaking generally, there are always three issues:
    1. Operator precedence: In algebra, 1 + 2 * 3 is always 7, not 6.
    2. Bitwise operators: Does, say, "&&" mean "logical and" or "bitwise and?" Is 7 && 16 ... true, or integer 0?
    3. Short-circuiting: The computer stops evaluating a logical expression that is joined by "and" and "or" operators as soon as possible. If you are counting on "side effects" from the entire expression, some of them might not happen.
      In algebra, 1 + 2 * 3 is always 7, not 6.

      in what world would it ever be 6?

        in a world where you stand on your head   ,-)
        (and have different precedences, of course)
        I'm sure that was supposed to be "9" but the point is made. Anyhow, "parentheses are your bestest friend," and so is splitting a complicated expression into several smaller ones using temporary local variables. Write the source-code so that people can understand it at a glance. Compilers and interpreters can take care of themselves. Troubles begin when people mis-read what is put in front of them.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1203767]
Approved by marto
Front-paged by haukex
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (3)
As of 2024-04-20 05:08 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found