In the case of a repeated string, we may simply want to print out lines
of 20 '-' characters (perhaps as boundary lines in a report). Doing
this with a loop is not difficult, though a little cumbersome given the
task:
print "This is the Header\n";
print '-' for 1 .. 20;
print "\n";
The x operator allows us to build this string in a single operation:
print "This is the Header\n";
print '-' x 20, "\n";
The x operator is a binary operator (takes two operands) and is context
sensitive both in terms of the context of the entire operation, and in
terms of the context of the left operand). The basic syntax is:
Left-EXPR x Right-EXPR
The right expression (right operand) is always considered to be in
scalar context and treated as an integer. The left expression (left
operand) may be either a scalar or a list value.
When the left operand is a scalar, as in the example above, the x
operator treats it as a string and returns a new string repeated by the
number given as the right operand. So, '-' x 20 returns a string of
20 '-' characters, and 'foo' x 2 returns the string 'foofoo'. This
evaluation remains the same whether the entire expression is in scalar
context or in list context --- in the example above the expression is
an argument to the print() function and therefore in list context.
The x operator can return repeated lists if used in list context and if
the left operand is a literal list (i.e., wrapped in parentheses):
my @array = (1,2,3) x 2;
print "@array" # prints: 1 2 3 1 2 3
You need to be careful to put the left operand in parentheses for list
repetition --- using a plain array will not behave as desired:
my @array = (1,12,42);
@array = @array x 2;
print "@array\n"; # prints: 33
In this case, because the left operand is not in parentheses it is
evaluated as a scalar, and an array in scalar context returns the
number of elements in the array --- in this case 3 --- thus the x
operator has returned the string '3' repeated twice.
Is this operator practical? Consider a case where you want to define a
ten-element array and initialize each element to 1:
my @array = (1) x 10; # my @array = (1,1,1,1,1,1,1,1,1,1);
Another useful case is initializing a hash when we've read in (or
otherwise obtained) a list of keys we wish to initialize to 1:
my @keys = qw(a b c d);
my %hash;
@hash{@keys} = (1) x @keys;
Lastly, a minor cautionary note --- remember that 'x' is not the
multiplication operator:
my $value = 15 x 2 / 3;
print "$value\n"; # prints: 505
Here the number 15 is treated as a string and repeated twice to get
1515 which is then treated as a number and divided by 3 to get 505
(rather than the result of 10 you might have wanted). This is one case
where Perl's natural conversion between numbers and strings without
warning can mean that a simple typo ('x' instead of '*') can lead to
strange results and is difficult to track down. So, if you have
calculations in your code and you are getting bizarre results you might
want to check for this particular typo.