trying to understand a hash

J

John

I'm taking apart somebody else's perl script in order to (a) learn and
(b) make something for my own purposes, and have come across a hash
that is not written in the manner to which I've become accustomed ...
the author is not within hollering distance, so I thought I'd try this
list for assistance.

Here's the hash as the author has created it:

$hashname{$key}{$other} = value;

where "$hashname" was initialized with "my %hashname", "$key" is a
scalar derived from input, and "$other" is another scalar also derived
from input.

It looks to me that "other" is outside of the key and obviously isn't
the value either. The script I found it in works as the author
intended, so the structure is obviously legal, but I don't understand
it. I was under the impression that a hash in scalar context should
look like:

$hashname{$key} = value;
or
%hashname(key => value);
or
%hashname("key","value");
but not
%hashname{$key}{$other} = value;

I thought maybe it was intended to be some kind of index notation, but
the actual value of that var is a string and not a digit, and if it
was supposed to be a reference of some sort to make or indicate the
key is another array (hash of hashes?), then I would expect the var
"$other" to be inside the key's curly braces, not outside in their own
braces (i.e. "$hashname{$key{$other}} = value;" as opposed to
"$hashname{$key}{$other} = value;).

Can somebody enlighten me on what that {$other} is all about? How
does it work? Why does it work?

best regards,

John
 
J

James E Keenan

John said:
I'm taking apart somebody else's perl script in order to (a) learn and
(b) make something for my own purposes,

Worthy objectives.

[snip]
Here's the hash as the author has created it:

$hashname{$key}{$other} = value;

where "$hashname" was initialized with "my %hashname", "$key" is a
scalar derived from input, and "$other" is another scalar also derived
from input.

It looks to me that "other" is outside of the key and obviously isn't
the value either. The script I found it in works as the author
intended, so the structure is obviously legal, but I don't understand
it. I was under the impression that a hash in scalar context should
look like:

$hashname{$key} = value;
or
%hashname(key => value);
or
%hashname("key","value");
but not
%hashname{$key}{$other} = value;
It's a hash of hashes, a multi-dimensional data structure. The value
associated with $hashname{$key} is a *reference* to another hash. In that
inner hash, a value is being assigned. Example:

use strict;
use warnings;
use Data::Dumper;

my (%hashname, $key, $other);

$key = 'alpha';
$other = 'beta';

$hashname{$key}{$other} = 'gamma';

print Dumper(\%hashname);

See: perldoc perlref

jimk
 
A

Amir Kadic

John said:
$hashname{$key}{$other} = value;

....which is the same as

$hashname{$key}->{$other}= value;

....because 'you can omit the arrow if and only if
it occurs between braces (or brackets)'.
I don't know where I read this, but hope it's correct.
Maybe `man perlreftut`...

Amir
 
D

Darren Dunham

John said:
I'm taking apart somebody else's perl script in order to (a) learn and
(b) make something for my own purposes, and have come across a hash
that is not written in the manner to which I've become accustomed ...
the author is not within hollering distance, so I thought I'd try this
list for assistance.
Here's the hash as the author has created it:
$hashname{$key}{$other} = value;
where "$hashname" was initialized with "my %hashname", "$key" is a
scalar derived from input, and "$other" is another scalar also derived
from input.
It looks to me that "other" is outside of the key and obviously isn't
the value either. The script I found it in works as the author
intended, so the structure is obviously legal, but I don't understand
it. I was under the impression that a hash in scalar context should
look like:
$hashname{$key} = value;
or
%hashname(key => value);
or
%hashname("key","value");
but not
%hashname{$key}{$other} = value;

This gets into references. You should go over the perlref and
perlreftut documents in perldoc if
you haven't already. The actual line is

$hashname{$key}{$other} = value;

and may also be written the following ways..

$hashname{$key}->{$other} = value;

$hashref = $hashname{$key}
${$hashref}{$other} = value;

%hashname has values in it that are not simple scalars, but are
references to more hashes.

%hashname = { key => { other => value } };

I thought maybe it was intended to be some kind of index notation, but
the actual value of that var is a string and not a digit, and if it
was supposed to be a reference of some sort to make or indicate the
key is another array (hash of hashes?), then I would expect the var
"$other" to be inside the key's curly braces, not outside in their own
braces (i.e. "$hashname{$key{$other}} = value;" as opposed to
"$hashname{$key}{$other} = value;).

Indeed "hash of hashes" is exactly how such a structure is named.

It's the way they're parsed. The above would require the presence of a
hash called %key.

Think of it like a multidimensional array.

$array[4][3] is also valid, but it's a array of arrays.
Can somebody enlighten me on what that {$other} is all about? How
does it work? Why does it work?

Start here.
perldoc perldsc
perldoc perlreftut
perldoc perlref

Come back if you have more questions... :)
 
M

Michael Budash

I'm taking apart somebody else's perl script in order to (a) learn and
(b) make something for my own purposes, and have come across a hash
that is not written in the manner to which I've become accustomed ...
the author is not within hollering distance, so I thought I'd try this
list for assistance.

Here's the hash as the author has created it:

$hashname{$key}{$other} = value;

where "$hashname" was initialized with "my %hashname", "$key" is a
scalar derived from input, and "$other" is another scalar also derived
from input.

It looks to me that "other" is outside of the key and obviously isn't
the value either. The script I found it in works as the author
intended, so the structure is obviously legal, but I don't understand
it. I was under the impression that a hash in scalar context should
look like:

$hashname{$key} = value;
or
%hashname(key => value);
or
%hashname("key","value");
but not
%hashname{$key}{$other} = value;

I thought maybe it was intended to be some kind of index notation, but
the actual value of that var is a string and not a digit, and if it
was supposed to be a reference of some sort to make or indicate the
key is another array (hash of hashes?), then I would expect the var
"$other" to be inside the key's curly braces, not outside in their own
braces (i.e. "$hashname{$key{$other}} = value;" as opposed to
"$hashname{$key}{$other} = value;).

Can somebody enlighten me on what that {$other} is all about? How
does it work? Why does it work?

best regards,

John

you were sooooo close. $hashname{$key}{$other} does indeed indicate a
"hash of hashes", or more specifically, a "hash of hash references",
since a hash value can only contain scalars.

so, since $hashname{$key} contains a hash ref, you can refer to one of
that hashref's keys in either of two ways:

$hashname{$key}->{$hashrefkey}

or

$hashname{$key}{$hashrefkey}

hth-
 
T

Tad McClellan

John said:
the author is not within hollering distance, so I thought I'd try this
list for assistance.


This is not a list (as in "email list"). This is a Usenet newsgroup.

where "$hashname" was initialized with "my %hashname",


$hashname has no relationship to %hashname.

$hashname{} has a relationship to %hashname.

(but we know what you meant)

I was under the impression that a hash in scalar context


A hash used in a scalar context is not useful to a Perl programmer,
it is only useful to a perl programmer.

(it returns 2 numbers with a slash between, try it:

print scalar(%hashname);
)

should
look like:

$hashname{$key} = value;
^
^

That is not a hash. That is only one element of a hash.

("one thing" is what dollar sign means.)


"a hash" includes _all_ of the keys and values.

("all of the pairs" is what percent sign means)

or
%hashname(key => value);
or
%hashname("key","value");
but not
%hashname{$key}{$other} = value;


None of those are Perl (5).

I thought maybe it was intended to be some kind of index notation,

Right!


but
the actual value of that var is a string and not a digit,


Perl has a data structure that is indexed by strings rather
than digits.

It is called "a hash". :)


You can tell it is a hash because it used curlies.

If it was an array at the 2nd level, it would have used squares.

$hashname{$key}[$other] = value; # $other better be a number

and if it
was supposed to be a reference of some sort to make or indicate the
key is another array (hash of hashes?),
^^^^^^^^^^^^^^

Exactly.

I thought you said you didn't understand it? :)

Can somebody enlighten me on what that {$other} is all about?


It is indexing a 2nd-level of hash.

How
does it work?


perldoc perlreftut


Put this in your code after %hashname has been loaded up, and you
can see its structure:

use Data::Dumper;
...
print Dumper \%hashname;

Why does it work?


Because that's the way Larry wanted it?
 
J

John

This is not a list (as in "email list"). This is a Usenet newsgroup.

My apologies, Tad, I didn't mean to denigrate this fine old pillar of
the internet ;-).
None of those are Perl (5).

What do you mean? The first two structures above are shown in my perl
book which specifically refers to perl 5.005 (the book is from a
programming class I took several years ago ... I know it's old, but
it's still handy). I seem to recall being told that the "=>" (arrow)
sign within a hash structure was a perl v5 feature not found in
previous versions.

O&BTW, what did you mean when you said "perl programmer" versus "Perl
programmer"? Is there some kind of class warfare involving leading
upper-case characters that I wasn't aware of? My pound-bang
specifically says /usr/bin/perl and not /usr/bin/Perl ... :) ...
anyhow, I'm not a progammer -- I'm a pseudo-sysadmin that hacks out
perl scripts to aid me with my daily grind, but I have not got (nor do
I desire) the depth of knowledge in any programming language to be
termed "a programmer".

No worries ... all the responses to my query were very helpful ... now
I comprehend the hash of hashes structure a bit better than before,
and that is a good thing.

So ... to summarize, the structure

%hashname{$key}{$other} = value;

represents a 'hash of hashes' where the hash defined as
"%hashname{$key}" dereferences to another hashname which is then
referenced by key "$other" to get (or set) the value "value".

It makes sense now that I look at it in that light, but my initial
confusion was probably caused a bit by not understanding the the order
of operation ... to use the HoH as above, the hash has to dereference
from left to right (first complete legal term dereferences before any
further terms are analyzed?) whereas I'm used to reading these things
from right to left ... I was thinking that the "$other" was a
modifier, or reference, to the term "$key", not the hash
"%hashname{$key}", and that was an incorrect belief on my part. Holy
cr@p, batman! Now all of a sudden all kinds of funky hashes I've seen
are starting to make sense!!!!! Whoa ... my head is spinning ...


Best regards,

John
 
T

Tad McClellan

John said:
My apologies, Tad, I didn't mean to denigrate this fine old pillar of
the internet ;-).


I point out the distinction not because mailing lists are "bad"
or "worse".

I point out the distinction because they are different dynamics,
with different rules of what is socially acceptable.

What do you mean?


$ perl -e '%hashname(key => value)'
syntax error at -e line 1, near "%hashname("
Execution of -e aborted due to compilation errors.

$ perl -e '%hashname("key","value")'
syntax error at -e line 1, near "%hashname("
Execution of -e aborted due to compilation errors.

$ perl -e '%hashname{$key}{$other} = value'
syntax error at -e line 1, near "%hashname{"
Execution of -e aborted due to compilation errors.


I mean that none of them are written in the Perl programming language.

I also mean that they _will_ be part of the Perl programming
language in a few more years, when Perl 6 is released.

The first two structures above are shown in my perl
book


It is a crap book then. Syntax errors are inexcusable.

which specifically refers to perl 5.005 (the book is from a
programming class I took several years ago ... I know it's old, but
it's still handy).


If it teaches non-Perl as Perl, then it is moving you _backwards_
in your understanding. Throw it in the trash (or sell it on E-bay).

I seem to recall being told that the "=>" (arrow)
sign within a hash structure was a perl v5 feature not found in ^^^^^^^^^^^^^^^^^^^^^^^
previous versions.


The "fat comma" ( => ) has nothing to do with a hash structure,
it just happens that that is where most people choose to use it.

(and yes, it was introduced in version 5.mumble-mumble).

It is just another way of writing a comma (with a little extra
treatment for the left-hand operand).

print 'hi' , ' ' , 'there';

print 'hi' => ' ' => 'there';

print hi => ' ' => there;

all make the same output.

O&BTW, what did you mean when you said "perl programmer" versus "Perl
programmer"?


That Question is Asked Frequently:

What's the difference between "perl" and "Perl"?


A hash in a scalar context is only useful to the C programmers
that work on the perl binary. It is useful for evaluating the
effectiveness of perl's built-in hashing algorithm.

Is there some kind of class warfare involving leading
upper-case characters that I wasn't aware of?


No, there is some kind of different semantic between when
you say "perl" and when you say "Perl".

My pound-bang
specifically says /usr/bin/perl and not /usr/bin/Perl ... :) ...


Which illustrates the difference rather nicely, as it is referring
to the perl binary (the interpreter) rather than to the Perl
programming language.

%hashname{$key}{$other} = value;


That still is not Perl. You must have meant this instead:

$hashname{$key}{$other} = 'value'; # barewords are "bad" too
^
^
represents a 'hash of hashes' where the hash defined as
"%hashname{$key}" dereferences to another hashname which is then
^^^^

No, it refers to another hash, whether that hash has a name or not.

The name of something is not the same as the something being named.

You can have named or anonymous hashes in Perl.

Holy
cr@p, batman! Now all of a sudden all kinds of funky hashes I've seen
are starting to make sense!!!!! Whoa ... my head is spinning ...


Welcome to our (Perl) world! :)
 
M

Michael P. Broida

John said:
So ... to summarize, the structure

%hashname{$key}{$other} = value;

represents a 'hash of hashes' where the hash defined as
"%hashname{$key}" dereferences to another hashname which is then
referenced by key "$other" to get (or set) the value "value".

Hmm. I missed the original post, but I don't think that:
%hashname{$key}
is valid anywhere. I've been doing a LOT of hash-of-
hash-of-hash-of-hash-of-hash-etc stuff these past few
months, and in NO case did it work with a leading
percent-sign. Perhaps there's some case where the
above syntax works, but I haven't seen it yet.

However,
$hashname{$key}
is valid. And:
$hashname{$key}{$other} = value;
can work as "hash of hashes". In both cases, the
declaration of the hash is:
%hashname

My point is that the "%" is used to declare the hash
or when referring to the -entire- hash. To look at any
part of the hash, you have to use the "$" and a key
in curlies.

Mike
 
G

Gunnar Hjalmarsson

Tad said:
A hash used in a scalar context is not useful to a Perl
programmer, it is only useful to a perl programmer.

(it returns 2 numbers with a slash between, try it:

print scalar(%hashname);
)

To me it may be useful to check whether the hash is empty:

if (%hash) {
do this;
} else {
do that;
}

And I can assure you that I'm not a perl programmer. :)
 
J

Jay Tilton

(e-mail address removed) (John) wrote:

: (e-mail address removed) (Tad McClellan) wrote in message
: :
: > > or
: > > %hashname(key => value);
: > > or
: > > %hashname("key","value");
: > > but not
: > > %hashname{$key}{$other} = value;
: >
: > None of those are Perl (5).
:
: What do you mean? The first two structures above are shown in my perl
: book

If the syntax errors are not simple transcription typos, then you have a
truly abysmal book. Please share its title with us so it may be placed
on the "trees killed for no reason" list.

The first two are hopeless. They resemble subroutine calls more than
they resemble any kind of hash usage.

The only one of those that comes close to being syntactically correct is
the third--replace the '%' sigil with a '$'.

: I seem to recall being told that the "=>" (arrow)
: sign within a hash structure was a perl v5 feature not found in
: previous versions.

The use of the "fat comma" arrow in the example above is not any kind of
mistake.

: So ... to summarize, the structure
:
: %hashname{$key}{$other} = value;
:
: represents a 'hash of hashes' where the hash defined as
: "%hashname{$key}" dereferences to another hashname which is then
: referenced by key "$other" to get (or set) the value "value".

Wrong sigils again. Change all those '%' to '$' .

Be cautious of thinking "dereferences to another hashname." That path
can lead to using symbolic references. See perlfaq7, "How can I use a
variable as a variable name?"

A hash does not need to have a name. The point of having a reference
(hash or otherwise) is that you don't care what its name is, or if it
has one at all.

: It makes sense now that I look at it in that light, but my initial
: confusion was probably caused a bit by not understanding the the order
: of operation ... to use the HoH as above, the hash has to dereference
: from left to right (first complete legal term dereferences before any
: further terms are analyzed?) whereas I'm used to reading these things
: from right to left

You might appreciate the dereferencing arrow operator.

$hashname{$key}->{$other} = 'value';

The arrow can be eliminated in that example without affecting anything,
but it nicely emphasizes that $hashname{$key} is a reference while
pointing your eyeballs in the right...er...the correct direction.

: Holy
: cr@p, batman! Now all of a sudden all kinds of funky hashes I've seen
: are starting to make sense!!!!! Whoa ... my head is spinning ...

Far out. Isn't it nice when code stops looking like Greek?
(Or Hebrew, considering your peculiar reading style. :)
 
T

Tad McClellan

The "fat comma" ( => ) has nothing to do with a hash structure,
it just happens that that is where most people choose to use it.
It is just another way of writing a comma (with a little extra
treatment for the left-hand operand).

print 'hi' , ' ' , 'there';

print 'hi' => ' ' => 'there';

print hi => ' ' => there;

all make the same output.


Errr, _maybe_ that last one makes the same output. It depends
on whether a there() function has been defined at this point
in the code.

I should have quoted the fat comma's right operand:

print hi => ' ' => 'there';
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top