Perl has a number of sigils:
$scalar = 1; # individual value
@array = ( 1, 2, 3, 4, 5 ); # sequence of values
%hash = ('it', 'ciao', 'en', 'hello', 'fr', 'salut'); # unordered key-value pairs
&function('arguments'); # subroutine
*typeglob; # symbol table entry
These look like sigils, but aren't:
\@array; # \ returns the reference of what's on the right (so, a reference to @array)
$#array; # this is the index of the last element of @array
You can use braces after the sigil if you should be so inclined. Occasionally, this improves readability.
say ${value} = 5;
While you use different sigils to define variables of different types, the same variable can be accessed in different ways based on what sigils you use.
%hash; # we use % because we are looking at an entire hash
$hash{it}; # we want a single value, however, that's singular, so we use $
$array[0]; # likewise for an array. notice the change in brackets.
@array[0,3]; # we want multiple values of an array, so we instead use @
@hash{'it','en'}; # similarly for hashes (this gives the values: 'ciao', 'hello')
%hash{'it','fr'}; # we want an hash with just some of the keys, so we use %
# (this gives key-value pairs: 'it', 'ciao', 'fr', 'salut')
This is especially true of references. In order to use a referenced value you can combine sigils together.
my @array = 1..5; # This is an array
my $reference_to_an_array = \@array; # A reference to an array is a singular value
push @array, 6; # push expects an array
push @$reference_to_an_array, 7; # the @ sigil means what's on the right is an array
# and what's on the right is $reference_to_an_array
# hence: first a @, then a $
Here's a perhaps less confusing way to think about it. As we saw earlier, you can use braces to wrap what's on the right of a sigil. So you can think of @{}
as something that takes an array reference and gives you the referenced array.
# pop does not like array references
pop $reference_to_an_array; # ERROR in Perl 5.20+
# but if we use @{}, then...
pop @{ $reference_to_an_array }; # this works!
As it turns out, @{}
actually accepts an expression:
my $values = undef;
say pop @{ $values }; # ERROR: can't use undef as an array reference
say pop @{ $values // [5] } # undef // [5] gives [5], so this prints 5
...and the same trick works for other sigils, too.
# This is not an example of good Perl. It is merely a demonstration of this language feature
my $hashref = undef;
for my $key ( %{ $hashref // {} } ) {
"This doesn't crash";
}
...but if the "argument" to a sigil is simple, you can leave the braces away.
say $$scalar_reference;
say pop @$array_reference;
for keys (%$hash_reference) { ... };
Things can get excessively extravagant. This works, but please Perl responsibly.
my %hash = (it => 'ciao', en => 'hi', fr => 'salut');
my $reference = \%hash;
my $reference_to_a_reference = \$reference;
my $italian = $hash{it}; # Direct access
my @greets = @$reference{'it', 'en'}; # Dereference, then access as array
my %subhash = %$$reference_to_a_reference{'en', 'fr'} # Dereference ×2 then access as hash
For most normal use, you can just use subroutine names without a sigil. (Variables without a sigil are typically called "barewords".) The &
sigil is only useful in a limited number of cases.
Making a reference to a subroutine:
sub many_bars { 'bar' x $_[0] }
my $reference = \&many_bars;
say $reference->(3); # barbarbar
Calling a function ignoring its prototype.
Combined with goto, as a slightly weird function call that has the current call frame replaced with the caller. Think the linux exec()
API call, but for functions.