Perl Language Variables Sigils


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.