laziness, impatience, and hubris PerlMonks

### in search of a more elegant if then else

 on Feb 18, 2010 at 23:46 UTC Need Help??

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

Hi all, for a while now i've been using quite a clumsy if then else block:
my \$var; if ( condition ) { \$var = value1; } else { \$var = value2; }
is there a better way of getting this done? it seems clumsy to me.

Replies are listed 'Best First'.
Re: in search of a more elegant if then else
by fullermd (Priest) on Feb 18, 2010 at 23:53 UTC

You can use the ternary operator

my \$var = (condition) ? value1 : value2;
Re: in search of a more elegant if then else
by toolic (Bishop) on Feb 18, 2010 at 23:53 UTC
The Conditional Operator is another way. You should decide, on a case-by-case basis, if it is better than an if/else.
my \$var = (condition) ? value1 : value2;
Re: in search of a more elegant if then else
by FunkyMonk (Chancellor) on Feb 19, 2010 at 11:10 UTC
As other Monks have suggested, the conditional operator does what you want. They have also pointed out that it can become difficult to read. However, if you set your code out carefully, the conditional operator can produce elegant and easy to read code. Consider:

my \$n = 3; my \$s = \$n == 1 ? 'one' : \$n == 2 ? 'two' : \$n == 3 ? 'three' : \$n == 4 ? 'four' : 'ETOOBIG'; print "\$n : \$s\n"; # 3 : three

But, in some circumstances, you may be able to use a hash table:

my %h = ( 1 => 'one', 2 => 'two', 3 => 'three', 4 => 'four' ); \$s = \$h{\$n} // 'ETOOBIG'; # needs perl 5.10 #\$s = \$h{\$n} || 'ETOOBIG'; # works for any perl print "\$n : \$s\n"

See perlop for the difference between the or (||) and defined or (//) operators

Unless I state otherwise, all my code runs with strict and warnings

And with 5.10 there is given/when

given ( \$n ) { when ( 1 ) { \$s = 'one'; } when ( 2 ) { \$s = 'twe'; } when ( 3 ) { \$s = 'three'; } when ( 4 ) { \$s = 'four'; } default { \$s = 'ETOOBIG'; } }

- doug

i should read the changes more, i love this! so simple and easy to understand.
Re: in search of a more elegant if then else
by Anonymous Monk on Feb 18, 2010 at 23:52 UTC
It is not clumsy
it may be correct syntax, but putting down 5 lines for something that can (now i've read comments) be done in one line seems a bit more elegant to me, and makes the code look a bit nicer.
Re: in search of a more elegant if then else
by Anonymous Monk on Feb 18, 2010 at 23:57 UTC
thanks for your help! i think this will make my code look a little better.. :-)

what are the up's and downs of using the ternary operator?
It gets unreadable for all but the most trivial of expressions, but it's perfect for assigning one of two values to a variable. Also useful in that area are
# Use default when val is my \$var = \$val || \$default; # ... false (= stringifies to '' or '0'). my \$var = \$val // \$default; # ... undefined. (Requires Perl 5.10.)
It gets unreadable for all but the most trivial of expressions

Right. It's possible to back yourself (or front yourself, if you're twisted :) into monstrosities with it. The classic C 12 Days of Christmas puts it to good (?) use, among its other distortions.

Like a lot of things in perl (or any language, really), you just have to keep an eye on yourself to be sure you stay inside the lines. My two rules of thumb are length and nestedness:

• If I start nesting, that's a sign I should write it out in more explicit form
• If it starts getting much longer than 1 line, or there're more than maybe one or two logical ops (&&, ||, etc) in the condition, I should probably switch to if/else

(None hard rules of course, but signs that I'm wandering off the beam and should take a step back to reevaluate)

If it "fits," and is easy to read, use the ternary. Otherwise, use the if-then. Think in terms of which one will be easier to understand when someone else - ie. your boss - will be looking over your shoulder while you try to figure out a bug in something you wrote \$x months or years ago.

Be kind to yourself.
I go for the Friday 4 p.m. test. It's broken, it's 4 p.m. on Friday, you've had a LOOONGGG week, and you want to think about going home.

Which one is going to be easier to read and fix?

You should note that the ternary operator and if-then-else don't do the same thing. The ternary operator is an operator, intended to return a value (which can be assigned, tested, or further operated upon). If-then-else executes one of two alternate blocks.

Just to blur the lines a little :)

print do{ if( \$_ ) { 'fred' }else{ 'bill' } } for 0, 1;; bill fred

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".
In the absence of evidence, opinion is indistinguishable from prejudice.
Re: in search of a more elegant if then else
by Anonymous Monk on Feb 19, 2010 at 19:03 UTC
A more general question is: what are you computing with this if statement?

If it's something interesting and complex, think about whether or not you can factor out some or all the functionality into it's own function, so you can re-use it elsewhere, and test it independently.

If it's something simple, then the number of lines you need to code it won't really matter.

For example, it's probably better to use this for a complicated condition:

\$score = skatingScore(\$technique, \$interpretation, isRussian(\$judge) ) +;
but you can use something like this for a simple one...
\$ranking = \$isDisqualified ? "N/A" : rank(\$score);

--
AC

Re: in search of a more elegant if then else
by rir (Vicar) on Feb 22, 2010 at 13:24 UTC
There is also shellish short circuiting. (I can't say that fast.)
\$var = "condition_false"; \$condition and \$var = "condition_true;
Be well,
rir

Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://824056]
Approved by toolic
Front-paged by ww
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (9)
As of 2021-12-09 11:40 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
R or B?

Results (36 votes). Check out past polls.

Notices?