3.8. Scalar and List ContextThis is the most important section in this chapter. In fact, it's the most important section in the entire book. In fact, it wouldn't be an exaggeration to say that your entire career in using Perl will depend upon understanding this section. So if you've gotten away with skimming the text up to this point, this is where you should really pay attention. That's not to say that this section is in any way difficult to understand. It's actually a simple idea: a given expression may mean different things depending upon where it appears. This is nothing new to you; it happens all the time in natural languages. For example, in English,[83] suppose someone asked you what the word "read"[84] means. It has different meanings depending on how it's used. You can't identify the meaning, until you know the context.
The context refers to where an expression is found. As Perl is parsing your expressions, it always expects either a scalar value or a list value.[85] What Perl expects is called the context of the expression.[86]
5 + something # The something must be a scalar sort something # The something must be a list Even if something is the exact same sequence of characters, in one case it may give a single, scalar value, while in the other, it may give a list.[87]
Expressions in Perl always return the appropriate value for their context. For example, how about the "name"[88] of an array. In a list context, it gives the list of elements. But in a scalar context, it returns the number of elements in the array:
@people = qw( fred barney betty ); @sorted = sort @people; # list context: barney, betty, fred $number = 5 + @people; # scalar context: 5 + 3 gives 8 Even ordinary assignment (to a scalar or a list) causes different contexts: @list = @people; # a list of three people $n = @people; # the number 3 But please don't jump to the conclusion that scalar context always gives the number of elements that would have been returned in list context. Most list-producing expressions[89] return something much more interesting than that.
3.8.1. Using List-Producing Expressions in Scalar ContextThere are many expressions that would typically be used to produce a list. If you use one in a scalar context, what do you get? See what the author of that operation says about it. Usually, that person is Larry, and usually the documentation gives the whole story. In fact, a big part of learning Perl is actually learning how Larry thinks.[90] Therefore, once you can think like Larry does, you know what Perl should do. But while you're learning, you'll probably need to look into the documentation.
Some expressions don't have a scalar-context value at all. For example, what should sort return in a scalar context? You wouldn't need to sort a list to count its elements, so until someone implements something else, sort in a scalar context always returns undef. Another example is reverse. In a list context, it gives a reversed list. In a scalar context, it returns a reversed string (or reversing the result of concatenating all the strings of a list, if given one): @backwards = reverse qw/ yabba dabba doo /; # gives doo, dabba, yabba $backwards = reverse qw/ yabba dabba doo /; # gives oodabbadabbay At first, it's not always obvious whether an expression is being used in a scalar or a list context. But, trust us, it will get to be second nature for you eventually. Here are some common contexts to start you off: $fred = something; # scalar context @pebbles = something; # list context ($wilma, $betty) = something; # list context ($dino) = something; # still list context! Don't be fooled by the one-element list; that last one is a list context, not a scalar one. If you're assigning to a list (no matter the number of elements), it's a list context. If you're assigning to an array, it's a list context. Here are some other expressions we've seen, and the contexts they provide. First, some that provide scalar context to something: $fred = something; $fred[3] = something; 123 + something something + 654 if (something) { ... } while (something) { ... } $fred[something] = something; And here are some that provide a list context: @fred = something; ($fred, $barney) = something; ($fred) = something; push @fred, something; foreach $fred (something) { ... } sort something reverse something print something 3.8.2. Using Scalar-Producing Expressions in List ContextGoing this direction is straightforward: if an expression doesn't normally have a list value, the scalar value is automatically promoted to make a one-element list: @fred = 6 * 7; # gets the one-element list (42) @barney = "hello" . ' ' . "world"; Well, there's one possible catch: @wilma = undef; # OOPS! Gets the one-element list (undef) # which is not the same as this: @betty = ( ); # A correct way to empty an array Since undef is a scalar value, assigning undef to an array doesn't clear the array. The better way to do that is to assign an empty list.[91]
3.8.3. Forcing Scalar ContextOn occasion, you may need to force scalar context where Perl is expecting a list. In that case, you can use the fake function scalar. It's not a true function, because it just tells Perl to provide a scalar context: @rocks = qw( talc quartz jade obsidian ); print "How many rocks do you have?\n"; print "I have ", @rocks, " rocks!\n"; # WRONG, prints names of rocks print "I have ", scalar @rocks, " rocks!\n"; # Correct, gives a number Oddly enough, there's no corresponding function to force list context. It turns out never to be needed. Trust us on this, too. Copyright © 2002 O'Reilly & Associates. All rights reserved. |
|