--- Oliver Glass <[EMAIL PROTECTED]> wrote:
> Hello,

Hiya. =o)

> Despite a fair amount of general coding experience I keep slipping up
> with hashes... I learnt them in a hurry and so am working on loose
> foundations.

lol -- I've *never* done *that* before... 
<sound effect of growing nose>

> Could anyone reccomend a tutorial on the subject, preferably aimed at
> a little higher than novice level?

I can blather, and folk can ask for clarification. That usually works
pretty well, since other folk are pretty good at answering specific
question! lol! Let me start at a little more basic level, though, and
work up. It gives me more chance to put my foot in my mouth, and then
when someone corrects me, *I* learn stuff!

A Hash is an associative array. Whereas "arrays" use square brackets to
and numbers indicate an index,

  $array[1]
 
"hashes" use curly braces and strings.

  $hash{'this'}

Unlike normal arrays, all hash keys must be unique, because (as I
understand it) a "hashing" algorithm is used on the key value to decide
where it goes, so that when retrieving the value it can go through the
same algorithm to go straight to the value, rather than having to walk
through them individually and do string compares. In general, hashes
are a little slower than arrays (I've heard 15-20%), and take up more
memory -- they allocate memory in blocks, and add more when the hash is
half full (?), so they tend to take up about four times as much space
as the data in them would in an array. They are wonderfully flexible,
however....

The elements of a hash must be scalars (DEFINITELY correct me on this
if I misrepresent!), but since references are scalars, a reference may
be stored, and the hash lookup mechanism will follow such linkages,
allowing complex and flexible multilevel structures. This is basically
the same way that multidimensional arrays are done, and as a result you
can create structures which include hashes of arrays of hashes of
values, if you want to get that fancy. Such a structure would be
accessed like this:

  $top{'key1'}[0]{'key2'} = $val;

Every indirection must be traced, however, so depending on your
processing needs, it's sometimes more efficient to compile the keys and
make one hash out of it:

  $top{'key1'.0.'key2'} = $val; # has been known to save me a LOT
                                # of time, memory, and headache

Hashes can also be used for complex access. When referring to an entire
hash, we use %, like this:

  print %hash;

The symbol used indicates the type of the final value, so in the
examples above, a scalar was being returned. It is possible, however,
to return a list by using the array character @. I have a module for
EBCDIC to ASCII conversions, which uses a hash table lookup; for the
reverse conversions, I just flipped and copied the table, like this:

 @ASCEBC{values %EBCASC} = keys %EBCASC; # flip for the compliment
table

What this does is assigns to %ASCEBC in a particular order, as
specified by the argument "{values %EBCASC}". the @ on @ASCEBC tells
perl I'm assigning an entire list at once, so what this statement does
is assigns to the values specified (as keys in %ASCEBC) from keys
%EBCASC.

Note that order for hashes, while predictable, is not intuitive; it's
based on the hashing algorith, ans seems quite random. The above code
works because the algorithm is constant, but don't think of it as
sorted. If the order matters, either don't use a hash, or order them
yourself somehow (which is a topic for another discussion, though maybe
not here. =o)

If one takes a reference to a hash, like this:

  $rh = \%hash;

then one can access it in several ways:

  $$rh{foo};  # same as $hash{foo}
  $rh->{foo}; # again, same as $hash{foo}
  keys %$rh   # same as keys %hash

This is commonly used as the mthod for objects, though it's best to use
accessors for the data, rather than fiddling with object properties
directly.

The constructor for an anonymous hash is curly braces, which return a
reference to the data they contain:

  $rh = { a => 1, b => 2 };

Now, to print 2, say:

  print $rh->{b};

A common mistake is to try using this constructor incorrectly, like
this:

  %hash = { a => 1, b => 2 };

This should give you an warning if you enable -w, saying the hash
assignment has only one element. You gave the hash a key with no value.
What was the key? the reference to the data that the {} returned. It
will *not* give you *any* clue as to what you have done wrong if you
don't use -w!

Ok, That should have been plenty of opportunity for me to stick my foot
in my mouth. =o)

Corrections?
Questions?



__________________________________________________
Do You Yahoo!?
Get personalized email addresses from Yahoo! Mail - only $35 
a year!  http://personal.mail.yahoo.com/

Reply via email to