Siaris
Simple Things
Syndicate: full/short
Siaris
Categories
General0
News2
Programming2
LanguageBits0
Perl50
Ruby10
VersionControl1
Misc1
Article Calendar
<= May, 2008
S M T W T F S
123
45678910
11121314151617
18192021222324
25262728293031
Search this blog

Key links
External Blogs
Brought to you by ...
Ruby
1and1.com

Repeating Yourself: The x Operator

Andrew L. Johnson (First published by ItWorld.com 2001-09-20)

Loops are the general mechanism for expressing repetition in code. However, there are a couple of instances where loops seem like overkill — repeating strings and repeating lists. For these cases, Perl provides the repetition operator (the ‘x’ operator).

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 (ie, 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 be 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.

*****