ZetCode

Perl context

last modified October 20, 2026

Context is one of the central ideas of Perl. Every expression is evaluated in a context that tells Perl whether the caller wants a single value or a list of values, and the result can differ. Understanding context explains many behaviours that seem puzzling, such as why an array in a number expression gives its length.

Scalar and list context

Every operation in Perl is evaluated in a context. The two main contexts are scalar context, where a single value is expected, and list context, where a list of values is expected. The same expression can produce different results in each. The left side of an assignment determines the context of the right side.

scalar_list.pl
#!/usr/bin/perl

use strict;
use warnings;
use v5.34.0;

my @colors = ('red', 'green', 'blue');

my $count = @colors;
my ($first) = @colors;
my @copy = @colors;

say "count: $count";
say "first: $first";
say "copy: @copy";

An array assigned to a scalar variable is evaluated in scalar context and yields the number of elements. In my ($first) = @colors the parentheses make the left side a list, so the array is evaluated in list context and its first element is stored. Assigning to an array copies all of the elements.

$ perl scalar_list.pl
count: 3
first: red
copy: red green blue

Forcing a context

Sometimes the context has to be selected explicitly. The scalar function forces scalar context, and so does a string concatenation or a numeric comparison.

force_context.pl
#!/usr/bin/perl

use strict;
use warnings;
use v5.34.0;

my @nums = (10, 20, 30);

say "Items: " . @nums;
say "Items: ", scalar(@nums);
say "Last index: $#nums";

if (@nums > 2) {
    say "more than two items";
}

my $last = (7, 8, 9)[-1];
say "last of list: $last";

The concatenation operator and the > comparison give @nums scalar context, so both see the element count. scalar(@nums) does the same explicitly, which is needed for example in the argument list of say. The expression $#nums is the index of the last element. A list slice such as (7, 8, 9)[-1] picks an element from a list.

$ perl force_context.pl
Items: 3
Items: 3
Last index: 2
more than two items
last of list: 9

Context-sensitive built-in functions

Many built-in functions return different results depending on the context of the call. The reverse function reverses a list in list context, but reverses the characters of a string in scalar context. The localtime and gmtime functions return a list of date parts in list context and a formatted string in scalar context.

builtins.pl
#!/usr/bin/perl

use strict;
use warnings;
use v5.34.0;

my $word = 'Perl';

my @chars = reverse split //, $word;
say "list reverse:   @chars";

my $rev = reverse $word;
say "scalar reverse: $rev";

my @parts = (gmtime(0))[5, 4, 3];
say "list gmtime:    @parts";

my $time = gmtime(0);
say "scalar gmtime:  $time";

Calling reverse on the characters of the word in list context gives the reversed list, while assigning to a scalar concatenates and reverses the string. Likewise gmtime(0) returns the epoch as a list of numbers, of which the slice picks the year offset, month and day, and as a readable string when assigned to a scalar.

$ perl builtins.pl
list reverse:   l r e P
scalar reverse: lreP
list gmtime:    70 0 1
scalar gmtime:  Thu Jan  1 00:00:00 1970

The wantarray function

A subroutine can find out the context it was called in with wantarray. It returns true in list context, false in scalar context, and undef in void context, when the return value is ignored.

wantarray.pl
#!/usr/bin/perl

use strict;
use warnings;
use v5.34.0;

sub whoami {
    return 'void'   unless defined wantarray;
    return 'list'   if wantarray;
    return 'scalar';
}

my @l = whoami();
my $s = whoami();
whoami();

say "list call:   $l[0]";
say "scalar call: $s";

sub report { say "called in ", (defined wantarray ? (wantarray ? 'list' : 'scalar') : 'void'), " context" }
report();
my $x = report();
my @y = report();

The whoami subroutine returns a different string for each context, and report prints it directly. The three calls of report show void context for a bare call, scalar context for an assignment to a scalar, and list context for an assignment to an array. This is how built-in functions such as localtime behave, and it lets custom functions do the same.

$ perl wantarray.pl
list call:   list
scalar call: scalar
called in void context
called in scalar context
called in list context

Returning arrays and lists

What a subroutine returns in scalar context depends on the form of the return expression. An array returns its element count, while a comma-separated list returns its last element.

return_context.pl
#!/usr/bin/perl

use strict;
use warnings;
use v5.34.0;

sub get_values {
    my @v = (4, 5, 6);
    return @v;
}

sub get_list {
    return (4, 5, 6);
}

my $n = get_values();
my $last = get_list();
my ($head) = get_list();
my @all = get_list();

say "array in scalar context: $n";
say "list in scalar context: $last";
say "first via list assign:  $head";
say "all: @all";

return @v evaluates the array in scalar context, so the caller gets 3. return (4, 5, 6) uses the comma operator, which in scalar context discards all values but the last, so the caller gets 6. Using my ($head) = get_list() puts the call in list context and takes the first element. When a function should behave sensibly in both contexts, check wantarray explicitly.

$ perl return_context.pl
array in scalar context: 3
list in scalar context: 6
first via list assign:  4
all: 4 5 6

Regular expressions and context

A pattern match also depends on context. In scalar context it returns true or false, in list context it returns the captured groups, and with the /g flag in list context all matches.

regex_context.pl
#!/usr/bin/perl

use strict;
use warnings;
use v5.34.0;

my $str = 'a1b22c333';

my $has = $str =~ /\d+/;
my ($num) = $str =~ /(\d+)/;
my @all = $str =~ /(\d+)/g;
my $count = () = $str =~ /\d+/g;

say "scalar match: $has";
say "first capture: $num";
say "all captures: @all";
say "match count: $count";

The first match is scalar and yields 1 for success. Wrapping the left side in parentheses gives the first captured group. With /g in list context all numbers are returned. The idiom my $count = () = ... assigns the match to an empty list, which is in list context, and then assigns the resulting element count to the scalar. It is known as the countof or goatse operator.

$ perl regex_context.pl
scalar match: 1
first capture: 1
all captures: 1 22 333
match count: 3

Boolean context and interpolation

Boolean context is a form of scalar context. An empty array or hash is false, a non-empty one is true. Inside double-quoted strings, an array is joined with spaces, but expressions such as scalar @items must be embedded with a reference trick.

boolean_interp.pl
#!/usr/bin/perl

use strict;
use warnings;
use v5.34.0;

my @empty = ();
my %h = (a => 1);
my @items = (1, 2, 3);

say "array is empty"  unless @empty;
say "hash has keys"   if %h;
say "items: ${\ scalar @items}";
say "items: @{[ scalar @items ]}";

my $n = @items;
my $str = "@items";
say "n=$n str=$str";

my %seen;
my @uniq = grep { !$seen{$_}++ } qw(a b a c b);
say "uniq: @uniq";
my $cnt = grep { $_ > 1 } @items;
say "grep count: $cnt";

The unless @empty and if %h tests need no explicit comparison. To interpolate the element count into a string, either ${\ scalar @items} or @{[ scalar @items ]} can be used; both evaluate the expression and insert the result. Interpolating "@items" joins the elements with the separator in $", which is a space by default. The grep function returns the matching elements in list context but their count in scalar context.

$ perl boolean_interp.pl
array is empty
hash has keys
items: 3
items: 3
n=3 str=1 2 3
uniq: a b c
grep count: 2

Best Practices

In this article we have covered scalar, list, boolean and void context in Perl, forcing a context with scalar, context-sensitive built-ins, wantarray, and the effect of context on returns and pattern matches.

Source

perldata: Context

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Perl tutorials.