Paul, thanks so much for all this information!

As well as helping me learn your kindness really brightened up a dreary
day at the office :)

Well, I've been working on hashes for the last few weeks and have some
more questions now. I've dropped them into our original correspondence.

Best wishes,

Oliver!

--- 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'}

---
what do the curly braces mean? are they used anywhere else in perl?
---

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!), 

----
this is correct, i checked in perldsc - data structures cookbook
----

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

----
can i create structures in perl, like in c? 
do i get this functionality with objects?
----

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}"

---
how are you setting the order here?
---

. 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.

---
i find this confusing... so you're saying if i have a hash

my %perl;
my %hash;

with some keys and values

%perl = (
        'intrest' => 'high',
        'knowledge' => 'sketchy'
);

i can assign to it as an array

@hash{values %perl} = keys %perl;

resulting in - if i print %hash:

sketchyknowledgehighintrest

could i do the same assignment with

%hash = %perl;

also, why when i print %perl do i get

intresthighknowledgesketchy

something to do with the order / hashing algorithm?
---

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

---
how do i create a new hash using this reference to populate it?
i imagined it would be done as:

my \%hash = $rh;

i.e. create a %hash, set its \reference to $rh

but this doesn't seem to work.
---

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};
  
---
why is the arrow being used here? what does it mean? where else is it
used?
---

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!

---
the right way to do this is with () instead of {}, right? i.e.
%hash = (a => 1, b => 2);
---

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

Corrections?
Questions?

---
could you please give some examples of uses of hashes?

i've used them in my own code to hold configurations loaded from a
config file, like
%config{'verbose'} = 0 etc.

what else are they good for? for what reasons would we choose them over
conventional arrays?
---

Reply via email to