Home Guest Book | Technical PagePersonal Page

About Me
Who is a Good QA
Latest News
Testing Concepts
Automation Tools
Agile Development
UNIX Basics
Perl Scripting
Imp. Commands
My Resume

Perl Hash Howto

This howto comes with no guaratees other than the fact that these code segments were copy/pasted from code that I wrote and ran successfully.

Initialize clear, or empty) a hash.

Assigning an empty list is the fastest method.


    my %hash = ();


People have asked how to initialize a hash reference (aka hash ref). It's just like any scalar variable; you can use my alone, or you can assign a value.

    my $hash_ref;
    my $hash_ref = 0;  # zero

Copy a hash.


    my %hash_copy = %hash;  # copy a hash

    my $href_copy = $href;  # copy a hash ref

Delete a single key/value pair.

The solution differs for a hash and a hash reference, but both cases can use the delete function.



    delete $hash{$key};

Hash reference:

    delete $hash_ref->{$key};

Perform an action on each key/value pair in a hash.

The actions below print the key/value pairs.


Use each within a while loop. Note that each iterates over entries in an apparently random order, but that order is guaranteed to be the same for the functions keys and values.

    while ( my ($key, $value) = each(%hash) ) {
        print "$key => $value\n";

A hash reference would be only slightly different:

    while ( my ($key, $value) = each(%$hash_ref) ) {
        print "$key => $value\n";


Use keys with a for loop.

    for my $key ( keys %hash ) {
        my $value = $hash{$key};
        print "$key => $value\n";


    my $file = $ARGV[0] || "-";

    my %from = ();

    open FILE, "< $file" or die "Can't open $file : $!";

    while( <FILE> ) {
        if (/^From: (.*)/) { $from{$1}++ }  # count recurrences of sender

    close FILE;

    for my $sender ( sort keys %from ) {
        print "$sender: $from{$sender}\n";

Get the size of a hash.


    print "size of hash:  " . keys( %hash ) . ".\n";


    my $i = 0;

    $i += scalar keys %$hash_ref;  # method 1: explicit scalar context
    $i += keys %$hash_ref;         # method 2: implicit scalar context

Use hash references.


    sub foo
        my $hash_ref;

        $hash_ref->{ 'key1' } = 'value1';
        $hash_ref->{ 'key2' } = 'value2';
        $hash_ref->{ 'key3' } = 'value3';

        return $hash_ref;

    my $hash_ref = foo();

    print "the keys... ", sort keys %$hash_ref, "...\n";

Function to build a hash of hashes; return a reference.


    sub foo
        my ( $login, $p, $uid, $gid, $gecos, $dir, $s );

        my %HoH = ();

        my $file = '/etc/passwd';
        open( PASSWD, "< $file" ) or die "Can't open $file : $!";

        while( <PASSWD> ) {
            ( $login, $p, $uid, $gid, $gecos, $dir, $s ) = split( ':' );

            $HoH{ $login }{ 'uid' } = $uid;
            $HoH{ $login }{ 'gid' } = $gid;
            $HoH{ $login }{ 'dir' } = $dir;

        close PASSWD;

        return \%HoH;

Access and print a reference to a hash of hashes.


    my $rHoH = foo();

    my( $uid, $gid, $dir );

    for my $login ( keys %$rHoH ) {

        $uid =       $rHoH->{ $login }->{ 'uid' };   # method 1  most readable
        $gid =    ${ $rHoH->{ $login } }{ 'gid' };   # method 2
        $dir = ${ ${ $rHoH }{ $login } }{ 'dir' };   # method 3 least readable

        print "uid: $uid, gid: $gid, dir, $dir.\n";


    my $rHoH = foo();

    for my $k1 ( sort keys %$rHoH ) {
        print "k1: $k1\n";
        for my $k2 ( keys %{$rHoH->{ $k1 }} ) {
            print "k2: $k2 $rHoH->{ $k1 }{ $k2 }\n";

Function to build a hash of hashes of hashes; return a reference.


    sub foo
        my %HoHoH = ();

        while( ... ) {

            if( /LOCATION:/ ) {


            } elsif( /MODULE:/ ) {

                $HoHoH{ $loc }{ $module_type }{ MODULE_NAME } = $module_name;

            } elsif( $ARGS_ALLOWED ) {

                $HoHoH{ $loc }{ $module_type }{ $arg_name } = $arg_value;



        return \%HoHoH;

Access and print a reference to a hash of hashes of hashes.


    my $rHoH = foo();

    for my $k1 ( sort keys %$rHoHoH ) {
        print "$k1\n";

        for my $k2 ( sort keys %{$rHoHoH->{ $k1 }} ) {
            print "\t$k2\n";

            for my $k3 ( sort keys %{$rHoHoH->{ $k1 }->{ $k2 }} ) {
                print "\t\t$k3 => $rHoHoH->{ $k1 }->{ $k2 }->{ $k3 }\n";

Print the keys and values of a hash, given a hash reference.


    while( my ($k, $v) = each %$hash_ref ) {
        print "key: $k, value: $v.\n";

Determine whether a hash value exists, is defined, or is true.


    print "Value EXISTS, but may be undefined.\n" if exists  $hash{ $key };
    print "Value is DEFINED, but may be false.\n" if defined $hash{ $key };
    print "Value is TRUE at hash key $key.\n"     if         $hash{ $key };


Let's say we execute an sql query where some of the resulting values may be NULL. Before attempting to use any of the values we should first check whether they are defined, as in the following code. Note that the subroutine sql_fetch_hashref() takes care of connecting to the database, preparing the statement, executing it, and returning the resulting row as a hash reference using DBI's fetchrow_hashref() method.

    my $answers = 'a,b,c,d,e';

    my $sql = "select max_time, $answers from questions " .
              'where question_number=?';
    my $hash_ref = sql_fetch_hashref( $sql, $q );

    my @answers = split ',', $answers;

    my $max_time = $hash_ref->{max_time} || '60';

    my $hash_ref_ans;
    for my $letter ( @answers ) {
        $hash_ref_ans->{ $letter } = $hash_ref->{ $letter }
            if defined $hash_ref->{ $letter };

The for loop made a new hash of only defined key/value pairs.

How to make hash of array

$Hash{$key} = \@Array -> @Array = @{$Hash{$key}}


Author of this page:





More on HASH

the hash structure is based upon a Perl hash table that associates keys with values


One-dimensional hashes



By one-dimensional Perl hash or simple hash we generally mean a hash whose elements are not references to other Perl structures (arrays or hashes). See %ages and %members hashes shown below for an example:

%ages = ("John", 43, "Paul", 25, "Marie", 22);

%members = (John => "father", Paul => "son",

                        Marie => "daughter");


Copy a hash


%destHash = %sourceHash;  # copy a hash

$destHasRef = $sourceHashRef;  # copy a hash ref

This is a shallow method to copy Perl hashes, and works well when we speak about oneĖdimensional hashes, with no references to other structures.

Create or initialize a hash

Perl hashes are structures and you do not need to allocate structures or other variables in Perl. The first time you use a hash type variable in your code, that variable will be automatically created. Please look at the following code:

%ages = ("John", 43, "Paul", 25, "Marie", 22);

%members = (John => "father", Paul => "son",

                      Marie => "daughter");

$agesRef = \%ages;

print $$agesRef{Marie}; #prints 22

In the above example, we used two ways to create/initialize a hash variable. In the first line we initialized the %ages hash variable with a list composed by pairing of keys and values, separated by commas. But Perl has a special "comma-arrow" (=>) operator that we used to initialize the %members hash variable in the second line of code. The left side of the comma-arrow operator is expected to be a simple string and therefore it is not necessary to be quoted.

The third line shows you how to define a hash reference in Perl. You can dereference Perl hashes using the notation %$hashRef. If you want to get a certain hash value, you can dereference it by using the notation $$hashRef{key} Ė the fourth line of the above snippet code shows you how to do that.

Iíll show you below the Perl hash table for both the %ages and %members hash variables.




















Empty or clear a hash

In order to initialize Perl hashes to an empty list, you can use the code line:

%hash = ();


Extract slices from a hash

Perl lets you extract slices from Perl hashes. Please look at the following code:

# define a hash

%cds = ("Dr. Hook"         => "Sylvias Mother",

            "Rod Stewart"    => "Maggie May",

            "Andrea Bocelli"  => "Romanza",

            "Kenny Rogers"  => "For the good times",

            "Bee Gees"        => "One night only",

            "Bonnie Tyler"    => "Hide your heart");


# we used the @ prefix because the return value

# represents a list

# we need to supply the keys for which we wanted

# to extract the values

@slice = @cds{"Dr. Hook","Kenny Rogers","Bee Gees"};

# we used the join function to print each string

# on a new line

print join("\n", @slice);

Running the code it will produce the output:

Sylvias Mother

For the good times

One night only



Find out if a hash variable contains references

An easy way to find out if a variable is a simple string or number, or a reference to an array or a hash or something else, is to use the ref function. The ref function has the syntax form:

ref EXPR

If EXPR is not specified, $_ will be used. This function returns an empty string if the EXPR/$_ is not a reference, and a string (the type of reference) otherwise. Look at the code below to see how it works:

# define some simple variables

# we can use the same name Ė colors for different things

$colors = "darkblue";

@colors = qw(blue, red, yellow, brown);

%colors = (c1 => "blue", c2 => "green", c3 => "yellow");


# define a hash with references

%moreColors = (1 => "white", 2 => \$colors,

                      3 => \@colors, 4 => \%colors);


# loop through %moreColors hash to find out the references

foreach $key (keys %moreColors)


  if (ref $moreColors{$key} eq "SCALAR") {

    print "$key: SCALAR\n";

  } elsif (ref $moreColors{$key} eq "ARRAY") {

    print "$key: ARRAY\n";

  } elsif (ref $moreColors{$key} eq "HASH") {

    print "$key: HASH\n";

  } elsif (ref $moreColors{$key} eq "") {

    print "$key: NO REFERENCE\n";



And here is what you get as output if you run the code:





Do you see the order (4 1 3 2) in which the keys were printed? Perl doesnít care about the sequential order (1 2 3 4) in which I initialized %moreColors hash! Remember, if you want to print Perl hashes in some order, you must sort the hashes yourself.

To sort a hash by key, you can use the following code lines:

# define a hash
%time = (hour => 12, min => 25, sec => 32, msec =>75);
# foreach loop
foreach $key (sort keys %time)
  print "$key: $time{$key}\n";


Sort or order a hash



To sort a hash by value, in a descending order, you can use the following code:

# define a hash
%v = (v1 => 75, v2 => 251, v3 => 3, v4 => 12);
# sort by value and put the keys in an array 
@keys = sort {$v{$b} <=> $v{$a}} keys %v;
# loop through array to print the hash pairs ordered
foreach $key (@keys)
  print "$key: $v{$key}\n";

If you will run the code, it will produce the following output:

v1: 251
v3: 75
v2: 12
v4: 3

In the example above, our hash has numerical values so we used the numerical operator "<=>" for the comparisons. If you want to sort the values lexically, you need to use the stringwise operator "cmp" instead of "<=>".

Insert or add new items into a hash

To insert a new (key, value) pair in a hash structure, you can use the syntax form:

$hash{"key"} = "value";

If hash doesnít exist, it will be created automatically by Perl. Please have a look at the following code to see some examples:

%ages = ("John", 43, "Paul", 25, "Marie", 22);

$ages{"Anne"} = 22;

$ages{"Paul"} = 24;

$ages{"Marie"} = 24 unless exists $ages{"Marie"} ;

$ages{"George"} = 51 unless exists $ages{"George"} ;

print %ages, "\n";



In the first line I initialized the %ages hash. In the second and the third lines I inserted two elements in the hash variable. Please beware that the key "Paul" already exists and its associated value was over-written with the new value (24). Please note the dollar sign in $ages{"Marie"} and remember that a single element of a hash is a scalar.


Loop or iterate through a hash

To loop or iterate through Perl hashes, you can use "each" function. This function iterates or loops through the (key, value) pairs of a hash, each (key, value) pair being returned as a two-element list. See the example below to find out how it works:

%phoneNumbers = ("Anne", "432566", "Paul", "231275", "Marie",


while (($key, $value) = each %phoneNumbers)


  print "$key has the phone number $phoneNumbers{$key}\n";


The code shown above will extract the keys and values from the %phoneNumbers hash and it will display as output:

Anne has the phone number 432566

Paul has the phone number 231275

Marie has the phone number 299302



Print a hash

Iíll show you how to print the keys/values of Perl hashes. Iíll assign some elements to a hash structure (by using the syntax: $hash{$key}=value;), then Iíll iterate through the elements of the hash structure in order to print its keys/values pairs, as you see in the following snippet code:

# Iíll create a new hash - %notebookPrices

# by assigning some elements to it:






# the next loop prints the keys/values of the hash

foreach $key (keys %notebookPrices)


  print "Key: $key, Value: \$$notebookPrices{$key}\n";


After running this code, youíll get the output:

Key: Acer, Value: $750

Key: Toshiba, Value: $650

Key: HP, Value: $550



Remove a key from a hash

If you want to remove a single hash (key, value) pair from Perl hashes, you can use the delete function, in one of the following syntax forms:

delete $hash{$key};

delete $hashRef->{$key};   # if you have a hash reference

delete $$hashRef{$key};     # if you have a hash reference

See the examples below about how to implement it:

%phoneNumbers = ("Anne", "408566", "Paul", "233375", "Marie",


delete $phoneNumbers {"Paul"};

delete $phoneNumbers {"John"};

$phoneNumbersRef = \%phoneNumbers;

delete $$phoneNumbersRef{"Anne"};


#print the hash (keys, values)

foreach $key (keys % phoneNumbers)


  print "Key: $key, Value: $phoneNumbers{$key}\n";


The second line of this snippet code will have as effect the deletion of the "Paul" key from the %phoneNumbers hash. In the third line of the code we try to delete an inexistent key from the hash, the script will not return any error and the %phoneNumbers hash will remain unchanged. The last line of the above code shows you how to delete a key when you have a hash reference (we used $$hashRef{$key} notation to dereference a certain hash value, but you can use $hashRef->{$key}, too).

Reverse a hash

Because a hash represents a list of (key, value) pairs, we can reverse such a list and after that each pair will become (value, key). We'll do this by using the reverse function. However, beware that the hash keys are unique and if the values of the source hash are not unique, some elements will be lost. I want to say that if you reverse again your resulting hash, itís possible to obtain a shorter hash. Here is an example how you can implement it:

# define a hash

%cds = ("Dr. Hook"        => "Sylvias Mother",

            "Andrea Bocelli" => "Romanza",

            "Bonnie Tyler"   => "Hide your heart");

%cdsReversed = reverse %cds;


# weíll use Data::Dumper module to see

# what it is in the hash

use Data::Dumper;

print Dumper(%cdsReversed);














Copyright © 2009 Kunal Saxena Inc. All rights reserved