25

Ternary Trouble in Perl

 5 years ago
source link: https://www.tuicool.com/articles/hit/auUzMfJ
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
vMnieiB.jpg!web

Ternary Trouble in Perl

I ran into a problem in Perl the other day that has perplexed me since, simply because I haven’t yet found an answer to it. Here’s my problem. Take the following examples:

Multi-Variable Assignment:

Perl allows for declaring multiple variables at the same time using syntax like this:

my ($var1, $var2) = (100, 200);
print "variable 1 is: $var1, variable 2 is: $var2 \n\n";

This would return the following result:

variable 1 is: 100, variable 2 is: 200

String Splitting:

Easy enough right? Perl also allows for splitting a string, as do most languages. The syntax for splitting a string looks something like this:

my $str1 = 'a sentence has many words';
my @arr1 = split / /, $str1;
foreach my $x (@arr1) {
print "word: $x \n";
}

The printed result from this example would give us the following:

word: a 
word: sentence 
word: has 
word: many 
word: words

Ternary Operators:

Lastly, Perl also allows for Ternary operators. These are a nice way of consolidating code, and keeping if else blocks all in one line, although there is some debate on which style is better and more readable. In any case, take the following string:

my $str2 = 'This string has two sentences -  A dash separates them';

Now if we wanted to split this based on a conditional statement, we could do something like this:

my @arr7;
if (index($str2, '-') != -1) {
@arr7 = split /-/,$str2;
} else {
@arr7 = split /:/,$str2;
}
print "========== array7[0]", $arr7[0], "\n";
print "========== array7[1]", $arr7[1], "\n";

This code, would give us an output of the following:

========== array7[0]This string has two sentences 
========== array7[1]  A dash separates them

However, we could get the same output writing less code by using a ternary operator. The above if/else block would give the same output if written as follows:

my (@arr2) = (index($str2, '-') != -1) ? split /-/,$str2 : split /:/,$str2;
print "arr2[0] is: ", $arr2[0], "\n";
print "arr2[1] is: ", $arr2[1], "\n";

Our output being:

arr2[0] is: This string has two sentences 
arr2[1] is:   A dash separates them

Now lets take the if/else block from earlier, and add two arrays. We’ll set the value of each array in the if else block. Our two strings again are the following:

my $str2 = 'This string has two sentences -  A dash separates them';
my $str4 = 'This string has different punctuation; a semicolon';

Our conditional statement is:

my (@arr5, @arr6);
if (index($str2, '?') != -1) {
@arr5 = split /j/,$str2;
@arr6 = split /k/,$str4;
} else {
@arr5 = split /-/,$str2;
@arr6 = split /;/,$str4;
}
print "array 5[0] is: ", $arr5[0], "\n";
print "array 5[1] is: ", $arr5[1], "\n";
print "array 6[0] is: ", $arr6[0], "\n";
print "array 6[1] is: ", $arr6[1], "\n";

and our output being the following:

array 5[0] is: This string has two sentences 
array 5[1] is:   A dash separates them
array 6[0] is: This string has different punctuation
array 6[1] is:  a semicolon

This is where I get stuck:

Now, it seems like, with all of this in mind, you should be able to combine all of the above into a one line ternary operator piece of code. We can declare multiple variables in a ternary block as we’ve seen earlier. So it seems like we should be able to do exactly the above code, but with a ternary instead of an if else block. Something like this:

my (<a href="http://twitter.com/arr3" data-href="http://twitter.com/arr3" title="Twitter profile for @arr3" rel="noopener" target="_blank">@arr3</a>, <a href="http://twitter.com/arr4" data-href="http://twitter.com/arr4" title="Twitter profile for @arr4" rel="noopener" target="_blank">@arr4</a>) = (index($str2, '-') != -1) ? split /-/,$str2, split /;/, $str4 : split /:/,$str2, split /;/, $str4;

This is basically doing the exact same thing, setting the value of the two arrays, in each part of the ternary conditional statement. However if we print the results:

print "array 3[0] is: ", $arr3[0], "\n";
print "array 3[1] is: ", $arr3[1], "\n";
print "array 4[0] is: ", $arr4[0], "\n";
print "array 4[1] is: ", $arr4[1], "\n";

We get the following output:

array 3[0] is: This string has two sentences 
array 3[1] is:   A dash separates them
array 4[0] is: 
array 4[1] is:

Even if you put both evaluation blocks in parenthesis, it still yields the same results. My conclusion is that the additional comma in each split function throws off the ternary conditional block, and doesn’t catch the second group. However, this is just a guess, as I haven’t found an answer elsewhere.

If anyone has any insight, I would be appreciative. Not that this would ever be a necessary thing to do in any real-world situation. But it just annoys me that it seems like it should work, but doesn’t, and I don’t know why!

uiiIRnB.png!web

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK