views:

287

answers:

3

PERL:: What is:

  1. (52-80)*42
  2. 42*(52-80)?

Ans: 1) -28 2) -1176. Why?

Have fun explaining/justifying this please!

#!/usr/bin/perl
use strict;
print 42*(52-80) , "\n";
print ((52-80)*42) , "\n";
print (52-80)*42 , "\n";
print "\n";
my $i=(52-80)*42;
print $i, "\n";

Output:

> -1176
> -1176-28
> -1176
+23  A: 

If you add use warnings; you'll get:

print (...) interpreted as function at ./test.pl line 5.
Useless use of a constant in void context at ./test.pl line 5
Alex Howansky
If I could +10 this answer I would.
CanSpice
+6  A: 

Thanks to Perl's wacky parsing rules (oh Perl, you kook!), these statements:

print ((52-80)*42) , "\n";
print (52-80)*42 , "\n";

Are interpreted as if they were written:

(print ((52-80)*42)), "\n";
(print (52-80))*42, "\n";

This is why you end up seeing -1176-28 on one line, and the expected blank line is missing. Perl sees (print-expr), "\n"; and simply throws away the newline instead of printing it.

John Kugelman
Any other choice would be just as wacky in other cases. Unless your real complaint is that parentheses should always be required around all the arguments?
ysth
+14  A: 

The warning that Alex Howansky aludes to means that

print (52-80)*42 , "\n"

is parsed as

(print(52-80)) * 42, "\n"

which is to say, a list containing (1) 42 times the result of the function print(-28), and (2) a string containing the newline. The side-effect of (1) is to print the value -28 (without a newline) to standard output.

If you need to print an expression that begins with parentheses, a workaround is to prepend it with +:

print +(52-80)*42, "\n"         #  ==> -1176
mobrule
Or just print to a filehandle, like any sane.... wait-a-second, I was about to use sane and Perl in the same sentence. What was I thinking?
Ben Voigt
Or just don't use implicit parentheses if you aren't sure how they'll be interpreted. Remember, folks, that shorthand is not mandatory.
Sorpigal
It's not a list (as the void context warning indicates).
ysth
It is a list (as you can tell by the comma). The void context warning is about the useless `"\n"` in the 2nd element of the list.
mobrule