Ternary Trouble in Perl

Written by ethan.jarrell | Published 2018/08/24
Tech Story Tags: programming | perl | web-development | web-design

TLDRvia the TL;DR App

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: aword: sentenceword: hasword: manyword: 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 sentencesarr2[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 sentencesarray 5[1] is: A dash separates themarray 6[0] is: This string has different punctuationarray 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 (@arr3, @arr4) = (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 sentencesarray 3[1] is: A dash separates themarray 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!


Published by HackerNoon on 2018/08/24