Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Statement Modifiers, Whaa?

by jcupp (Acolyte)
on May 09, 2002 at 04:55 UTC ( #165251=perlquestion: print w/ replies, xml ) Need Help??
jcupp has asked for the wisdom of the Perl Monks concerning the following question:

MoNkS! Why do statement modifiers 'if' and 'unless' work different in this case. 'if' and 'while' work, but 'unless' seems broken. Is there a precedence issue here? I know the style is funny, but I'm experimenting :)
$nice = 0; sub hello1 { return "Get Lost!" unless $nice or return "Hi" } sub hello2 { return "Get Lost!" if not $nice or return "Hi" } print hello1, hello2

Comment on Statement Modifiers, Whaa?
Download Code
Re: Statement Modifiers, Whaa?
by emilford (Friar) on May 09, 2002 at 05:50 UTC
    I'm not sure why, but this could help you on your way to an answer. I was a bit confused by the output as well. It seems as if both should print the same message, seeing how unless is merely the negated form of if (ie - if not). I switched the or's to ||'s and got the expected output. Don't ask me why! Monks? -Eric
Re: Statement Modifiers, Whaa?
by hopes (Friar) on May 09, 2002 at 05:50 UTC
    It's because of precedence.

    not have more precedence than the others you're using. You are making this:
    return "Get Lost!" if (not $nice) or return "Hi"
    while what you want is this:
    return "Get Lost!" if not ($nice or return "Hi")



    Hopes
    $_=$,=q,\,@4O,,s,^$,$\,,s,s,^,b9,s, $_^=q,$\^-]!,,print
      This is where the Perl compiler becomes your best friend. If you run perl -MO=Deparse,-p [your script name here], the presedence Perl sees will be printed out. See below for your code example from above, which I stored in hello.pl.
      [cmilfo@cmilfo monks]$ perl -MO=Deparse,-p hello.pl ($nice = 0); sub hello1 { (($nice or return('Hi')) or return('Get Lost!')); } sub hello2 { (((!$nice) || return('Hi')) and return('Get Lost!')); } print(hello1(), hello2()); hello.pl syntax OK
      It basically puts in all the () and {} that we may not see.

      Cheers!
      Casey
Semantics! - Re: Statement Modifiers
by gmax (Abbot) on May 09, 2002 at 09:12 UTC
    Beyond the precedence problem, you are mixing two pieces of syntax that should not go together. When dealing with modifiers, if you are in doubt, try to read the statement outloud. If it doesn't make sense to you, then it is likely to be incorrect, not syntactically, but semantically.
    (BTW, the statement with "if" was giving back a correct result. hopes modification makes both results the same, but both wrong!)

    Now, let's point out a semantic problem that you might face using code like this.
    Perl statement modifiers were designed to simplify reading, not to complicate it.
    If your idea was to print "Get Lost!" when $nice is false, and "Hi" otherwise, then you should use a syntax that allows for alternatives.
    Statements like this one (especially with dubious semantics) can confuse both the programmer and the reviewer.
    My choice would be:
    sub hello3 { if ($nice) { return "Hi" } else { return "Get Lost!" } }
    Now, in this snippet it's easy to understand what I want. I would even use the ternary operator, because (once you get used to it) it is clear what it means.
    sub hello3 { return $nice ? "Hi" : "Get Lost!" }
    I use "unless" in cases where the alternative is not needed.
    print "you were asking for it!" unless $nice; # or a return statement, # when you just need to check a requirement # in the middle of a sub sub hello { return "get lost" unless $nice; # more statements return "hi" }
    "or" should be used after an assertive statement ("You behave or I teach you a lesson").
    $nice > 0 or print "Now I am goin to teach you ...";
     _  _ _  _  
    (_|| | |(_|><
     _|   
    
Re: Statement Modifiers, Whaa?
by BUU (Prior) on May 09, 2002 at 12:59 UTC
    shouldnt that be
    sub hello { return ("Get Lost!" unless $nice) or return "Hi!";
      Afraid not, invalid perl. Assuming the clause within the return did compile it'd never get to the 2nd return, it'd just return "Get Lost" or false. trinary operator is really what the author is searching for here (as gmax pointed out so eloquently).

      --
      perl -pew "s/\b;([mnst])/'$1/g"

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://165251]
Approved by vek
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (5)
As of 2014-07-26 06:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (175 votes), past polls