In Modern Perl, chromatic explains that Perl uses context to determine how an expression behaves. Two important concepts are amount context and value context.
Amount context determines whether Perl expects no result, a single scalar result, or a list of results.
| Context | Meaning | Example |
|---|---|---|
| Void | The result is not needed. | find_chores(); |
| Scalar | One scalar result is expected. | my $result = find_chores(); |
| List | A list of results is expected. | my @results = find_chores(); |
Consider this example:
my @numbers = (10, 20, 30); my $result1 = @numbers; my @result2 = @numbers; my ($result3) = @numbers;
What are the results?
The difference between the following two assignments is particularly important:
my $result = @numbers; my ($result) = @numbers;
In the first assignment, @numbers is evaluated in scalar context. An array in scalar context returns its number of elements: 3.
In the second assignment, the right-hand side is evaluated in list context. The list is assigned to the variables on the left, so $result receives the first element: 10.
Parentheses alone do not create a list. In this example, the parentheses on the left-hand side make it a list of variables, imposing list context on the right-hand side.
This distinction is particularly important when calling functions, because a function can behave differently depending on its calling context.
Value context determines how Perl interprets data. Three important kinds are numeric, string, and Boolean context.
Numeric operators expect numbers.
my $x = "12"; my $y = $x + 3; print $y . "\n"; # 15
The + operator imposes numeric context. Perl converts the string "12" into the number 12.
String operators expect strings.
my $x = 12; my $y = $x . "3"; print $y . "\n"; # 123
The . operator concatenates strings. The number 12 is therefore converted to the string "12".
Boolean context determines whether a value is true or false.
my $name = "Reinier";
if ($name) {
print "The name exists.\n";
}
The if condition evaluates $name in Boolean context.
In Perl, 0, "" (the empty string), and undef are false. The string "0" is also false. Most other values are true.
A common source of errors is confusing numeric and string comparisons.
my $a = "10"; my $b = "2"; print "Equal numerically\n" if $a == $b; print "Equal as strings\n" if $a eq $b;
Neither message is printed.
| Operator | Context | Purpose |
|---|---|---|
| == | Numeric | Compare numerical values. |
| eq | String | Compare strings. |
| if | Boolean | Test whether a value is true. |
For example:
print "Equal numerically\n" if "02" == "2"; print "Equal as strings\n" if "02" eq "2";
The first message is printed, but the second is not.
Sometimes you want to make the intended context explicit.
my $number = 0 + $value; # Numeric context my $string = '' . $value; # String context my $boolean = !!$value; # Boolean context
These are useful techniques to recognise, although ordinary operators that naturally impose the required context are generally preferable.
The two kinds of context answer different questions.
| Context | Question | Examples |
|---|---|---|
| Amount context | How much data? | Void, scalar, list |
| Value context | What kind of value? | Numeric, string, Boolean |
Think of them as two independent dimensions.
For example:
my @numbers = (10, 20, 30); my $count = @numbers;
Here:
A subtle but important point: scalar context does not always mean that Perl returns the first element of a list. Arrays, for example, return their element count in scalar context. The result depends on the expression being evaluated.
When reading Perl code, ask two questions:
These questions explain many otherwise puzzling Perl expressions and are especially useful when debugging functions, array assignments, and hash initialisation.
Source: chromatic, Modern Perl, Chapter 1, "The Perl Philosophy," section "Context."