Velocity Reviews > Perl > if .. then .. else shorthand problem

# if .. then .. else shorthand problem

Justin C
Guest
Posts: n/a

 07-21-2009

I've only just started using the shorthand for the "if .. then .. else"
statement: (test) ? this : or_that;

Here's what I have:

use strict;
use warnings;

my \$weight = 40.18;

my \$half_kilos = (( int(\$weight) -30 ) * 2);
print "\$half_kilos\n";
if ( ((\$weight - 30) - (int(\$weight) - 30)) != 0 ) {
( (\$weight - int(\$weight)) < 0.5 ) ? \$half_kilos += 1 : \$half_kilos += 2;
print "\$half_kilos\n";
}

I expect \$half_kilos to be 21. Failing that, 22. But I get 23!

There's probably something really simple here I've not spotted, can
someone please enlighten me? I admit that my example would be clearer
written as a regular 'if...then...else', but I'd only just remembered
these and had used one (in a simpler form), and wanted to drum it in, so
used it again... I can remember how they work now... but can't get this
one to work.

Justin.

--
Justin C, by the sea.

J. Gleixner
Guest
Posts: n/a

 07-21-2009
Justin C wrote:
> I've only just started using the shorthand for the "if .. then .. else"
> statement: (test) ? this : or_that;
>
> Here's what I have:
>
> use strict;
> use warnings;
>
> my \$weight = 40.18;
>
> my \$half_kilos = (( int(\$weight) -30 ) * 2);
> print "\$half_kilos\n";
> if ( ((\$weight - 30) - (int(\$weight) - 30)) != 0 ) {
> ( (\$weight - int(\$weight)) < 0.5 ) ? \$half_kilos += 1 : \$half_kilos += 2;
> print "\$half_kilos\n";
> }
>
> I expect \$half_kilos to be 21. Failing that, 22. But I get 23!
>
> There's probably something really simple here I've not spotted, can
> someone please enlighten me? I admit that my example would be clearer
> written as a regular 'if...then...else', but I'd only just remembered
> these and had used one (in a simpler form), and wanted to drum it in, so
> used it again... I can remember how they work now... but can't get this
> one to work.
>

Maybe this will show the issue more clearly.
my \$weight = 40.18;

my \$half_kilos = (( int(\$weight) -30 ) * 2);
print "\$half_kilos\n";
if ( ((\$weight - 30) - (int(\$weight) - 30)) != 0 ) {
( (\$weight - int(\$weight)) < 0.5 )
? \$half_kilos .= 'a'
: \$half_kilos .= 'b';
print "\$half_kilos\n";
}
20
20ab

Solutions:

\$half_kilos += ( (\$weight - int(\$weight)) < 0.5 ) ? 1 : 2;

or

( (\$weight - int(\$weight)) < 0.5 )
? ( \$half_kilos += 1 )
: ( \$half_kilos += 2 );

Justin C
Guest
Posts: n/a

 07-22-2009
OK, I see the error of my ways. The bottom line, I think, to get the
result you expect, is to always use parens for that type of statement.

Thanks to B&B, JG, and Tony for the help.

Justin.

--
Justin C, by the sea.

Uri Guttman
Guest
Posts: n/a

 07-22-2009
>>>>> "JC" == Justin C <(E-Mail Removed)> writes:

JC> OK, I see the error of my ways. The bottom line, I think, to get the
JC> result you expect, is to always use parens for that type of statement.

nope. the bottom line is that you shouldn't do side effects with ?:. its
purpose is to return a value selected by a boolean test. the key word is
'return'. since perl allows side effects in expressions you are allowed
to put them inside ?: but it is very bad practice even if you use
parens. it is bypassing the purpose of the operator. if you want side
effects based upon a boolean, use if/else statements.

uri

--
Uri Guttman ------ http://www.velocityreviews.com/forums/(E-Mail Removed) -------- http://www.sysarch.com --
----- Perl Code Review , Architecture, Development, Training, Support ------
--------- Free Perl Training --- http://perlhunter.com/college.html ---------
--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------

Ted Zlatanov
Guest
Posts: n/a

 07-22-2009
On Tue, 21 Jul 2009 14:21:26 -0000 Justin C <(E-Mail Removed)> wrote:

JC> I've only just started using the shorthand for the "if .. then .. else"
JC> statement: (test) ? this : or_that;

JC> Here's what I have:

JC> use strict;
JC> use warnings;

JC> my \$weight = 40.18;

JC> my \$half_kilos = (( int(\$weight) -30 ) * 2);
JC> print "\$half_kilos\n";
JC> if ( ((\$weight - 30) - (int(\$weight) - 30)) != 0 ) {
JC> ( (\$weight - int(\$weight)) < 0.5 ) ? \$half_kilos += 1 : \$half_kilos += 2;
JC> print "\$half_kilos\n";
JC> }

JC> I expect \$half_kilos to be 21. Failing that, 22. But I get 23!

JC> There's probably something really simple here I've not spotted, can
JC> someone please enlighten me? I admit that my example would be clearer
JC> written as a regular 'if...then...else', but I'd only just remembered
JC> these and had used one (in a simpler form), and wanted to drum it in, so
JC> used it again... I can remember how they work now... but can't get this
JC> one to work.

I think you need to look at rounding and try to formulate the
calculation in general math terms, not if-then-else statements. What
you're doing above is like using a rock to open the window.

Ted