Perl¶
Sigils¶
The Perl sigils can be confusing sometimes. Consider the following example:
1 2 3 | my @arr = (1, 2, 3, 'foo');
my $x = $arr[2];
print "$x\n";
|
It’s not hard to understand that the code above prints “3”. What feels
strange to me is the line my $x = $arr[2]. Perl lists can contain only
scalar values. So assigning an element extracted from a list to a scalar
($x in our case) makes perfect sense. But why it’s $arr[2] and not
@arr[2]? It’s an array we’re working with in the first place, isn’t it?
Well… Let’s give it a try:
1 2 3 | my @arr = (1, 2, 3, 'foo');
my $x = @arr[2]; # <-- @ instead of $
print "$x\n";
|
Perl complains that Scalar value @arr[2] better written as $arr[2] at foo.pl
line 2, but in the end prints the expected “3”.
The answer to why Perl complains and why @arr[2] gives the same result can
be found in Perldoc. It turns out that @arr[2] actually means slice
of length 1. In other words, the @arr[2] approximately equals to
($arr[2]). Next, the slice is assigned to the scalar variable $x.
Recall that an array in the scalar context means its length, f.e.
1 2 3 | my @xs = (1, 2, 3, 4, 5);
my $z = @xs;
print "$z\n";
|
prints “5” which is the length of the array @xs.
You may expect that it’s also true for slices, but it isn’t. print "$x\n";
in the example outputs “3”, not “1” which is the length of the
@arr[2] slice!
Let’s get back to the original example and modify it a little:
1 2 3 | my @arr = (1, 2, 3, 'foo');
my $x = @arr[2, 3];
print "$x\n";
|
It prints “foo” - not the length of the slice as we have already seen. That’s because, according to Perldoc:
“Slices in scalar context return the last item of the slice.”
And that is why $x equals 3 in the second example - it’s
not the length but the last element of a single element slice.
Summing up:
- To access the first list element, the
$arr[0]syntax should be used. - The
@arr[0]syntax is used for slices. - The two forms above assigned to a scalar give visually the same result, but they actually differ since the first returns the first element and the second returns the last element of a single element slice.
- Arrays and slices meaning in the scalar context is different.
Now, what about hashes?
Here is an example of getting the value by the key:
1 2 3 | my %h = ('a' => 42, 'b' => 100);
my $y = $h{'a'};
print "$y\n"; # prints 42
|
Note the syntax $h{'a'} which resembles the one for arrays.
What will happen if we change the sigil $ to % in $h{'a'}?
1 2 3 | my %h = ('a' => 42, 'b' => 100);
my $y = %h{'a'}; # <-- % instead of $
print "$y\n";
|
Perl complains that %h{"a"} in scalar context better written as $h{"a"} at
foo.pl line 2. and prints “42”.
Let’s go straight to Perldoc and check what the $h{'a'} syntax means.
This thing is called “key/value hash slice”. In the example above $h{'a'}
returns a slice that contains the key ('a') and the value (42). In
other words – ('a', 42). This slice is assigned to the scalar
variable $y. According to the rules of interpretation of slices in the
scalar context, “42” (the last element of the slice) is assigned to $y.
See also