Question

The following code outputs nothing:

print (1 == 2)."a";

As does this:

print qw< One Two Three > . "a";

But this outputs a snowman followed by the letter a, as expected:

print chr(0x2603)."a";

Is there a general method of concatenating general "things", for lack of a better word (such as function output and the results of boolean comparisons) with string fragments that always works? Because the . operator doesn't seem to be reliable.

Was it helpful?

Solution

This is expected behavior due to the way lists and contexts work in Perl.

What's Happening

The line

print (1 == 2)."a";

Is parsed like this:

( print( 1 == 2 ) . "a" )

Since 1==2 returns an empty string, nothing is printed. The return value from print itself is then concatenated with a and discarded.

If you had turned on use warnings (which you should always do, along with use strict) you would have seen:

print (...) interpreted as function at -e line 1.
Useless use of concatenation (.) or string in void context at -e line 1.

The line

print qw< One Two Three > . "a";

Does, in fact, print the string Threea. That's because qw< One Two Three > is equivalent to the expression ( 'One', 'Two', 'Three' ). The concatenation operator . puts that expression in scalar context, and the behavior of the comma operator in scalar context is to return its right-hand operand. The expression thus reduces to Threea. Again, if you had warnings on, you would have seen:

Useless use of a constant ("One") in void context at -e line 1.
Useless use of a constant ("Two") in void context at -e line 1.

The moral of the story

use strict;
use warnings;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top