? : statement not working as expected

  • Thread starter Patrick Hartman
  • Start date
P

Patrick Hartman

Hi, I am trying to use ? : statements instead of if/else blocks
wherever possible to keep my code shorter. Below is a conditional
statement that for some reason is not working as expected with the ? :
method:

#!/usr/bin/perl -w
use strict;

# image name
my $image = 'yf446_mk_nb_0_0_6_ia';

# break out seperate pieces
my($bare_style,$color,$brand,$slot1,$slot2,$shot,$type) = $image =~ m/
^(\w+)_(\w+)_(\w+)_(\w+)_(\w+)_(\w+)_(\w+)$/;


# this is not working as expected, returns the 'else' result
{
my $style;
$brand eq 'nb' ? $style = $bare_style . $color : $style =
$bare_style;
print "?: version: $style\n";
}

# this works as expected
{
my $style;

if ($brand eq 'nb') {
$style = $bare_style . $color;
}
else {
$style = $bare_style;
}

print "if/else block version: $style\n";
}


Any ideas why this would not work in the first statement? I appreciate
it,

Patrick
 
U

Uri Guttman

PH> Hi, I am trying to use ? : statements instead of if/else blocks
PH> wherever possible to keep my code shorter. Below is a conditional
PH> statement that for some reason is not working as expected with the ? :
PH> method:

this is a classic newbie misuse of ?:.

PH> my $style;
PH> $brand eq 'nb' ? $style = $bare_style . $color : $style =
PH> $bare_style;
PH> print "?: version: $style\n";

$style = $brand eq 'nb' ? "$bare_style$color" : $bare_style ;

?: is meant to return an expression based on a boolean. it it NOT meant
to do side effects like assignment. you could fix your code with () but
it would still be wrong. the issue was precedence. the proper solution i
pasted above. the whole idea is to assign once but choose what to
assign. then the precedence (= is higher binding than ?:) works to your
advantage.

and given what you are doing, there are other ways too:

$style = $bare_style . ($brand eq 'nb' ? $color : '') ;

$style = $bare_style ;
$style .= $color if $brand eq 'nb' ;

uri
 
T

Ted Zlatanov

PH> # image name
PH> my $image = 'yf446_mk_nb_0_0_6_ia';

PH> # break out seperate pieces
PH> my($bare_style,$color,$brand,$slot1,$slot2,$shot,$type) = $image =~ m/
PH> ^(\w+)_(\w+)_(\w+)_(\w+)_(\w+)_(\w+)_(\w+)$/;

Doesn't it bother you that there's so much repetition there?

split('_', $image) will return a list of elements just as easily.

Also note that \w will match the '_' character as well so your
expression can only work accidentally.

PH> # this is not working as expected, returns the 'else' result
PH> {
PH> my $style;
PH> $brand eq 'nb' ? $style = $bare_style . $color : $style =
PH> $bare_style;
PH> print "?: version: $style\n";
PH> }

Never, ever assign in a conditional. Those who break that rule usually
do it for a very good reason (e.g. in an input loop) but 99% of the time
you simply should not do it.

PH> # this works as expected
PH> {
PH> my $style;

PH> if ($brand eq 'nb') {
PH> $style = $bare_style . $color;
PH> }
PH> else {
PH> $style = $bare_style;
PH> }

PH> print "if/else block version: $style\n";
PH> }

PH> Any ideas why this would not work in the first statement? I appreciate
PH> it,

Uri explained, but really, which one would you rather see in a program?

Ted
 
P

Patrick Hartman

Thanks for the explanation and insight Uri and Ted, I appreciate it. I
am clearly using the conditional too often (yes I am a newbie). Also
Ted thanks for pointing out the problem with my expression, I forgot
that \w includes stuff besides letters.

Patrick
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top