3

I came across with these two lines, and though I've been trying to figure out what they do, I'm still in doubt about their meaning in the code. The piece of code I am talking about is:

my $mapped_from = ($num_phones_in == 60)? = $1 : $2;
my $mapped_to = ($num_phones_out == 48)? = $2 : $3;

I don't really understand what a variable between parentheses followed by a question mark do ()?. And also I don't know what those two numbers with dollar sign (as variables) separated by colon mean.

To give you more details about the code, in this part I'm working with a file that look like this:

ah X /
au u aU

Where the columns have 60, 48 and 39 lines respectively. I would really appreciate if someone could give me a clue since I am a bit lost.

14
my $mapped_from = ($num_phones_in == 60)? = $1 : $2;

That's a syntax error. The test ? val_true : val_false is the "ternary operator", an inline form of an if-else statement. If test is true, it evaluates to the val_true part, and if test is false, it evaluates to the val_false part. The question mark has nothing to do with the parenthesis. But = $1 isn't a valid expression.

Without the extra =, ($num_phones_in == 60)? $1 : $2; would check if $num_phones_in is sixty, and return $1 or $2 accordingly.

$1 and $2 (etc.) are variables that refer to the contents of the capture groups in the previous regex. If you did "afoob" =~ /a(.*)b/, then $1 would contain foo. See Variables related to regular expressions in perlvar.

  • Thanks for such a great explanation!!! yes, I've already checked that the extra equals symbol = has to be removed in order to continue with the script without any error. And I'd not heard about "ternary operator" but I will definitely read a bit more about it :D – little_mice Jan 27 '18 at 12:57
6

The ? : is called a ternary operator, and is said to be one of the most abused operators in any modern language. (Nested ternary operators, particularly.) These two lines are equivalent:

$value = ($a > 9) ? 10 : 0;

if ($a > 9) { $value = 10 } else { $value = 0 };

The $1 and $2 you also ask about are the result of bracketed matches in the most recent Regular Expression. For example,

$a = 'Hello world. 1+2 is 3';
$a =~ /(\w+).*?(\d+)/;
print "1=$1, 2=$2\n";.   # "1=Hello, 2=1"
  • 2
    @JeffSchaller, Perl subs take their parameters in the @_ array, and scripts in @ARGV. – ilkkachu Jan 27 '18 at 13:12
  • Thanks for the correction @ilkkachu! I’ll delete my mistaken comment shortly. Sorry for the distraction, @roaima! – Jeff Schaller Jan 27 '18 at 13:48
0

DIY

Meta-answer: find out for yourself.

Perl has the very nifty debug mode. You can enter it thusly:

perl -de1

(This is just a handy shortcut for -d (debug mode) and -e 1 (execute the statement "1"), which is a trivial no-op with the benefit of minimal amount of characters to type).

Then you are prompted with a debugger where you can enter perl code which will be executed immediately. Try this:

$num_phones_in = 10;
my $mapped_from = ($num_phones_in == 60)? = $1 : $2;

You will get a syntax error straight away. The second = needs to go away. And for good readability, either remove all space for the ?: operator, or add spaces, whatever you want. Perl does not care, but your colleagues will.

my $mapped_from = ($num_phones_in == 60)?$1:$2;
my $mapped_from = ($num_phones_in == 60) ? $1 : $2;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.