Ksh Associative Array Assignment In Perl

Go to the first, previous, next, last section, table of contents.

Associative Arrays (Hashes)

This chapter will introduce the third major Perl abstract data type, associative arrays. Also known as hashes, associative arrays provide native language support for one of the most useful data structures that programmers implement--the hash table.

What Is It?

Associative arrays, also frequently called hashes, are the third major data type in Perl after scalars and arrays. Hashes are named as such because they work very similarly to a common data structure that programmers use in other languages--hash tables. However, hashes in Perl are actually a direct language supported data type.


We have seen that each of the different native data types in Perl has a special character that identify that the variable is of that type. Hashes always start with a .

Accessing a hash works very similar to accessing arrays. However, hashes are not subscripted by numbers. They can be subscripted by an arbitrary scalar value. You simply use the to subscript the value instead of as you did with arrays. Here is an example:

use strict; my %table; $table{'schmoe'} = 'joe'; $table{7.5} = 2.6;

In this example, our hash, called, , has two entries. The key is associated with the value , and the key is associated with the value .

Just like with array elements, hash elements can be used anywhere a scalar variable is permitted. Thus, given a @hash{%table} built with the code above, we can do the following:

print "$table{'schmoe'}\n"; # outputs "joe\n" --$table{7.5}; # $table{7.5} now contains 1.6

Another interesting fact is that all hash variables can be evaluated in the list context. When done, this gives a list whose odd elements are the keys of the hash, and whose even elements are the corresponding values. Thus, assuming we have the same from above, we can execute:

my @tableListed = %table; # @tableListed is qw/schmoe joe 7.5 1.6/

If you happen to evaluate a hash in scalar context, it will give you if no entries have yet been defined, and will evaluate to true otherwise. However, evaluation of hashes in scalar context is not recommended. To test if a hash is defined, use .


"Hash literals" per se do not exist. However, remember that when we evaluate a hash in the list context, we get the pairs of the hash unfolded into the list. We can exploit this to do hash literals. We simply write out the list pairs that we want placed into the hash. For example:

use strict; my %table = qw/schmoe joe 7.5 1.6/;

would give us the same hash we had in the previous example.


You should realize that any function you already know that works on arrays will also work on hashes, since you can always evaluate a hash in the list context and get the pair list. However, there are a variety of functions that are specifically designed and optimized for use with hashes.

Keys and Values

When we evaluate a hash in a list context, Perl gives us the paired list that can be very useful. However, sometimes we may only want to look at the list of keys, or the list of values. Perl provides two optimized functions for doing this: and .

use strict; my %table = qw/schmoe joe smith john simpson bart/; my @lastNames = keys %table; # @lastNames is: qw/schmoe smith simpson/ my @firstNames = values %table; # @firstNames is: qw/joe john bart/


The function is one that you will find particularly useful when you need to go through each element in the hash. The function returns each key-value pair from the hash one by one as a list of two elements. You can use this function to run a across the hash:

use strict; my %table = qw/schmoe joe smith john simpson bart/; my($key, $value); # @cc{Declare two variables at once} while ( ($key, $value) = each(%table) ) { # @cc{Do some processing on @scalar{$key} and @scalar{$value}} }

This terminates because returns when all the pairs have been exhausted. However, be careful. Any change in the hash made will "reset" the function for that hash.

So, if you need to loop and change values in the hash, use the following across the keys:

use strict; my %table = qw/schmoe joe smith john simpson bart/; foreach my $key (keys %table) { # Do some processing on $key and $table{$key} }


It turns out you can slice hashes just like you were able to slice arrays. This can be useful if you need to extract a certain set of values out of a hash into a list.

use strict; my %table = qw/schmoe joe smith john simpson bart/; my @friends = @table{'schmoe', 'smith'}; # @friends has qw/joe john/

Note the use of the in front of the hash name. This shows that we are indeed producing a normal list, and you can use this construct in any list context you would like.

Context Considerations

We have now discussed all the different ways you can use variables in list and scalar context. At this point, it might be helpful to review all the ways we have used variables in different contexts. The table that follows identifies many of the ways variables are used in Perl.

ExpressionContextVariableEvaluates to
scalar , a scalar the value held in
list , an array the list of values (in order) held in
scalar , an array the total number of elements in (same as )
scalar , an array the th element of
scalar , an array the subscript of the last element in (same as )
list , an array a slice, listing two elements from (same as )
scalar (interpolated) , a scalar a string containing the contents of
scalar (interpolated) , an array a string containing the elements of , separated by spaces
list , a hash a list of alternating keys and values from
scalar , a hash the element from with the key of
list , a hash a slice, listing two elements from (same as

Go to the first, previous, next, last section, table of contents.

Shells with associative arrays

Some modern shells provide associative arrays: ksh93, bash ≥4, zsh. In ksh93 and bash, if is an associative array, then is the array of its keys:

In zsh, that syntax only works in ksh emulation mode. Otherwise you have to use zsh's native syntax:

also works if does not have an empty key.

In zsh, you could also loop on both eys and alues at the same time:

Shells without associative arrays

Emulating associative arrays in shells that don't have them is a lot more work. If you need associative arrays, it's probably time to bring in a bigger tool, such as ksh93 or Perl.

If you do need associative arrays in a mere POSIX shell, here's a way to simulate them, when keys are restricted to contain only the characters (ASCII digits, letters and underscore). Under this assumption, keys can be used as part of variable names. The functions below act on an array identified by a naming prefix, the “stem”, which must not contain two consecutive underscores.

(Warning, untested code. Error detection for syntactically invalid stems and keys is not provided.)


Leave a Reply

Your email address will not be published. Required fields are marked *