Siaris

Context is Everything
01 Mar 01 - http://www.siaris.net/index.cgi/Programming/LanguageBits/Perl/20010301.rdoc

There are two main contexts that you really must be aware of when writing Perl programs: Scalar context and List context. Things can behave differently when evaluated in one or the other of these contexts.

Probably the most well know example is assigning an array:

    my @list   = @array; # @array is in list context
    my $scalar = @array; # @array is in scalar context

In the first case above, @array is being assigned to another array, providing list context, so it returns the list of its contents. In the second example, @array is being assigned to a scalar variable thus putting it in scalar context — an array in scalar context returns the size of the array. Now, one twist on the second example above is:

    my ($scalar) = @array; # @array is in list context;

Here the parentheses around the scalar mean that the left hand side of the assignment is a list of scalars (in this case, a list of length one), thus the @array is in list context. Now @array returns the list of its contents and the first element is assigned to $scalar (the rest of the list returned by the array is ignored).

Another example is using the keys() function of a hash — in list context it returns the list of keys in the given hash, but in scalar context it returns the number of keys in the hash. A hash itself in list context returns the full list of key value pairs (in the same sequence as the keys() function returns the keys), but in scalar context it does something rather different — it returns information about the underlying hash structure:

    my %hash = (one => 1, two => 2);
    print %hash, "\n";        # prints: one1two2
    print scalar %hash, "\n"; # prints: 2/8

The print() function provides a list context (the function expects to receive a list of arguments). The scalar() function can be used to explicitly evaluate an expression in a scalar context (as we do in the last example above). That final version is telling us that our hash currently has 8 buckets allocated and that two are being used.

Now, we’ve already seen that functions can return different things depending on context with the keys() function. Another example is the localtime() function (see: perldoc -f localtime). Operators can also act context dependently, as with the match operator m// (and that behavior is also modified by the /g modifier). The x operator (string replication) works differently if its left hand side is a scalar or a list.

Functions themselves may also supply context to their arguments. Take the join() function for example — the first thing it expects as an argument is a scalar value holding the string to be used as the join separator. If you thought you could just put all the arguments to join into a single array and pass that you wouldn’t get the results you wanted:

    my @args = (":", 1,2,3);
    my $str = join @args;
    print $str;              # $str is empty

Here the join() function expected a scalar as the first argument an so evaluated the @args array in a scalar context to get the separator character (in this case the size of the array which is 4), and there weren’t any following arguments to join together.

If a function or operator behaves differently depending on scalar or list context it is documented in the relevant documentation pages (see the perlfunc and perlop manpages).

*****