LearnAI ToolsCareerPractice BuildsPlayContact
Lesson 917 min read

Hashes

Learn Perl hashes: the % sigil, storing key-value pairs, accessing values with $hash{key}, and iterating with keys and values.

Introduction

A hash is Perl's built-in way of storing data as key-value pairs, letting you look up a value instantly by a meaningful name instead of a numeric position. If arrays are for ordered lists, hashes are for labeled data — think of a dictionary, a phone book, or a configuration file.

What You Will Learn
  • What a hash is and how the % sigil works.
  • How to declare a hash and access individual values.
  • How to check whether a key exists and delete entries.
  • How to iterate over every key and value in a hash.

What is a Hash?

A hash stores an unordered collection of key-value pairs. Every key is unique within a given hash, and each key maps to exactly one scalar value. Hash variable names use the % sigil.

use strict;
use warnings;
my %capitals = (
"France" => "Paris",
"Japan" => "Tokyo",
"Kenya" => "Nairobi",
);
print "Capital of Japan: $capitals{Japan}\n";
Program Output

Click Run to see what this code prints.

The => symbol, called the "fat comma," works exactly like a regular comma but visually pairs a key with its value, and it also automatically quotes a bareword on its left side, which is why "France" could just as easily be written without quotes as France =>.

Declaring a Hash

You can declare a hash empty and fill it in gradually, or initialize it all at once as shown above. Both approaches are common depending on whether your data is known upfront or built up as your script runs.

use strict;
use warnings;
my %inventory; # empty hash
$inventory{"apples"} = 50;
$inventory{"bananas"} = 30;
$inventory{"cherries"} = 120;
print "Apples in stock: $inventory{apples}\n";
Program Output

Click Run to see what this code prints.

Notice the sigil switch again, just like with arrays: the whole hash is %inventory, but a single value is accessed with $inventory{key}, because one value is a scalar.

Accessing and Updating Values

Reading and writing a hash value use the exact same $hash{key} syntax — Perl figures out from context whether you are reading or assigning.

use strict;
use warnings;
my %prices = (
coffee => 3.50,
tea => 2.75,
);
print "Coffee costs \$$prices{coffee}\n";
$prices{coffee} = 4.00; # update an existing value
$prices{juice} = 3.25; # add a brand new key
print "Updated coffee price: \$$prices{coffee}\n";
print "New juice price: \$$prices{juice}\n";
Program Output

Click Run to see what this code prints.

Checking for Keys and Deleting Entries

Before accessing a key that might not exist, it is good practice to check for it with the exists function, which avoids autovivification (Perl accidentally creating an empty entry just because you referenced it). The delete function removes a key-value pair entirely.

use strict;
use warnings;
my %prices = (
coffee => 4.00,
tea => 2.75,
);
if (exists $prices{tea}) {
print "Tea is on the menu at \$$prices{tea}\n";
}
if (!exists $prices{soda}) {
print "Soda is not on the menu.\n";
}
delete $prices{tea};
if (!exists $prices{tea}) {
print "Tea has been removed from the menu.\n";
}
Program Output

Click Run to see what this code prints.

keys and values

The keys function returns a list of all keys in a hash, and values returns a list of all corresponding values. Because a hash is inherently unordered, the order these come back in is not guaranteed to match your original insertion order.

use strict;
use warnings;
my %capitals = (
France => "Paris",
Japan => "Tokyo",
Kenya => "Nairobi",
);
my @countries = sort keys %capitals;
print "Countries: @countries\n";
my @cities = sort values %capitals;
print "Cities: @cities\n";
Program Output

Click Run to see what this code prints.

Wrapping keys %capitals in sort gives predictable, alphabetical output — a very common pattern, since hash order alone cannot be relied on.

Looping Over a Hash

The most common way to process every key-value pair is to loop over the sorted keys and look up each corresponding value inside the loop.

use strict;
use warnings;
my %capitals = (
France => "Paris",
Japan => "Tokyo",
Kenya => "Nairobi",
);
foreach my $country (sort keys %capitals) {
print "$country -> $capitals{$country}\n";
}
Program Output

Click Run to see what this code prints.

Common Mistakes

Avoid These Mistakes
  • Using $hash{$key} without quotes around a bareword key when the key is meant to be a literal string — usually fine, but can misbehave with keys that look like function calls.
  • Assuming hash order matches insertion order — it does not; sort explicitly if order matters.
  • Accessing a key that might not exist without checking exists first, which can silently autovivify empty entries in nested structures.
  • Mixing up %hash (the whole hash) with $hash{key} (one value) — the sigil switch is easy to forget.

Best Practices

  • Use exists to check for a key before assuming it is present, especially with user-supplied data.
  • Sort keys explicitly with sort keys %hash whenever consistent output order matters.
  • Choose hashes when you need to look values up by a meaningful name; choose arrays when order matters more than naming.
  • Use delete to remove entries cleanly instead of setting a value to undef, which leaves the key present.

Frequently Asked Questions

Yes, though Perl internally treats all hash keys as strings, so numeric keys are automatically stringified for lookup purposes.

delete removes the key entirely, so exists returns false afterward. Setting a value to undef keeps the key present with an undefined value, so exists would still return true.

Perl's hash implementation is optimized for fast lookups, not insertion order, and deliberately randomizes iteration order between runs for security reasons. Always sort explicitly if a specific order is required.

Key Takeaways

  • A hash stores unique keys mapped to scalar values, using the % sigil.
  • Access or assign a single value with $hash{key}; the whole hash is %hash.
  • exists checks for a key without creating it; delete removes a key-value pair entirely.
  • keys and values return lists of a hash's keys and values, respectively, in no guaranteed order.
  • Sort keys explicitly whenever consistent iteration order is required.

Summary

You now know all three of Perl's core data types: scalars, arrays, and hashes. Next, we will dig into one of Perl's most distinctive concepts — scalar versus list context — and revisit lexical scoping with my in more depth.

Next Lesson →

Variables & Context