trying to understand a hash

Discussion in 'Perl Misc' started by John, Oct 8, 2003.

  1. John

    John Guest

    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
    John, Oct 8, 2003
    #1
    1. Advertising

  2. "John" <> wrote in message
    news:...
    > 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
    James E Keenan, Oct 8, 2003
    #2
    1. Advertising

  3. John

    Amir Kadic Guest

    John wrote:

    > $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
    Amir Kadic, Oct 8, 2003
    #3
  4. John <> wrote:
    > 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... :)


    --
    Darren Dunham
    Unix System Administrator Taos - The SysAdmin Company
    Got some Dr Pepper? San Francisco, CA bay area
    < This line left intentionally blank to confuse you. >
    Darren Dunham, Oct 8, 2003
    #4
  5. In article <>,
    (John) wrote:

    > 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-
    --
    Michael Budash
    Michael Budash, Oct 8, 2003
    #5
  6. John <> wrote:

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


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
    Tad McClellan, Oct 8, 2003
    #6
  7. John

    John Guest

    Re: trying to understand a hash - understanding has occured

    (Tad McClellan) wrote in message news:<>...
    >
    > 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 ;-).

    > > 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 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
    John, Oct 9, 2003
    #7
  8. Re: trying to understand a hash - understanding has occured

    John <> wrote:
    > (Tad McClellan) wrote in message news:<>...
    >>
    >> 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 ;-).



    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.


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

    >>
    >>
    >> None of those are Perl (5).
    >>

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


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
    Tad McClellan, Oct 9, 2003
    #8
  9. Re: trying to understand a hash - understanding has occured

    John wrote:
    > 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
    Michael P. Broida, Oct 9, 2003
    #9
  10. Tad McClellan wrote:
    > 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. :)

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
    Gunnar Hjalmarsson, Oct 9, 2003
    #10
  11. John

    Jay Tilton Guest

    Re: trying to understand a hash - understanding has occured

    (John) wrote:

    : (Tad McClellan) wrote in message
    : news:<>...
    :
    : > > 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. :)
    Jay Tilton, Oct 9, 2003
    #11
  12. Re: trying to understand a hash - understanding has occured

    I myself <> wrote:


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


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
    Tad McClellan, Oct 10, 2003
    #12
  13. John

    Guest

    Re: trying to understand a hash - understanding has occured

    (Tad McClellan) wrote:
    > I myself <> wrote:
    >
    > > 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.


    s/defined/declared/

    :)
    , Oct 10, 2003
    #13
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Paul K

    Trying to understand...

    Paul K, Nov 19, 2003, in forum: ASP .Net
    Replies:
    2
    Views:
    345
    Paul K
    Nov 19, 2003
  2. =?Utf-8?B?QmlsbCBCb3Jn?=

    Trying to understand ticket/cookie expiration

    =?Utf-8?B?QmlsbCBCb3Jn?=, Oct 8, 2004, in forum: ASP .Net
    Replies:
    0
    Views:
    356
    =?Utf-8?B?QmlsbCBCb3Jn?=
    Oct 8, 2004
  3. rp
    Replies:
    1
    Views:
    516
    red floyd
    Nov 10, 2011
  4. Srijayanth Sridhar
    Replies:
    19
    Views:
    612
    David A. Black
    Jul 2, 2008
  5. Sherm Pendley
    Replies:
    8
    Views:
    132
    Tad McClellan
    Jun 24, 2005
Loading...

Share This Page