Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl one line if statement

I have a statement

$set eq "Y" ? $set = "N" : $set = "Y";

But no matter what it always sets to "N"

# Toggle setting
if ($set eq "Y")
{
   $set = "N";
}
else
{
   $set = "Y";
}

Why doesn't the one liner seem to work?

like image 730
Eric Fossum Avatar asked Mar 14 '12 21:03

Eric Fossum


People also ask

What does =~ do in Perl?

9.3. The Binding Operator, =~ Matching against $_ is merely the default; the binding operator (=~) tells Perl to match the pattern on the right against the string on the left, instead of matching against $_.

How do I print a Perl script?

print() operator – print operator in Perl is used to print the values of the expressions in a List passed to it as an argument. Print operator prints whatever is passed to it as an argument whether it be a string, a number, a variable or anything. Double-quotes(“”) is used as a delimiter to this operator.


Video Answer


5 Answers

Due to precedence rules, perl is not parsing your statement as you think:

$ perl -MO=Deparse,-p -e '$set eq "Y" ? $set = "N" : $set = "Y"'
((($set eq 'Y') ? ($set = 'N') : $set) = 'Y');
-e syntax OK

So as you see, in both conditions, the final result is the $set scalar which then gets set to Y.

You can fix it with a few parens:

$set eq "Y" ? $set = "N" : ($set = "Y")

But why repeat the assignment:

$set = $set eq 'Y' ? 'N' : 'Y';
like image 121
Eric Strom Avatar answered Oct 03 '22 23:10

Eric Strom


Operator precedence. What you've written is equivalent to

($set eq "Y" ? $set = "N" : $set) = "Y";

If you insist on writing such terse code, this make more sense:

$set = ( $set eq "Y" ? "N" : "Y" );
like image 31
Keith Thompson Avatar answered Oct 04 '22 01:10

Keith Thompson


It's about precedence; let's do the intent with parenthesis, and then let Perl remove them again:

perl -MO=Deparse -e '($set eq "Y") ? ($set = "N") : ($set = "Y"); print $set'
$set eq 'Y' ? $set = 'N' : ($set = 'Y');
print $set;
-e syntax OK

Which is thus the parenthesing required to do as you intended.

like image 43
jørgensen Avatar answered Oct 04 '22 00:10

jørgensen


If you rather not use "C" style conditional statements, you can do the same thing with 2 lines:

my $set = "Y"; #Set the scope and default value
$set = "N" if ($set eq "Y");

I personally recommend the "C" style described by others above... it easily demonstrates the two options a variable can be.

However, the method I show is great when dealing with a single conditional result.

like image 45
Negative Zero Avatar answered Oct 04 '22 01:10

Negative Zero


$set = ($set eq "Y") ? "N" : "Y";

should work

like image 41
David Harris Avatar answered Oct 03 '22 23:10

David Harris