HoHoH (hash of HoH's)

Discussion in 'Perl Misc' started by Aaron DeLoach, Jul 18, 2004.

  1. Hi All,

    I have a file that contains either a hash, or a HoH on each line. I am
    creating sub that will read the file and return ONE hash containing all the
    other hashes (as sub-hashes?). This way I can access each of the
    hashes/HoH's "through" the returned hash. Whew... I'm all hashed out!

    I need some direction on how to build the "return" hash from the file
    contents.

    Regards,
    Aaron
     
    Aaron DeLoach, Jul 18, 2004
    #1
    1. Advertising

  2. Aaron DeLoach

    Anno Siegel Guest

    Aaron DeLoach <> wrote in comp.lang.perl.misc:
    > Hi All,
    >
    > I have a file that contains either a hash, or a HoH on each line.


    A text file doesn't contain hashes, it contains text. How do you extract
    a hash (of hashes) from each line?

    That some of the hashes are actually hashes of hashes makes no essential
    difference.

    > I am
    > creating sub that will read the file and return ONE hash containing all the
    > other hashes (as sub-hashes?). This way I can access each of the
    > hashes/HoH's "through" the returned hash. Whew... I'm all hashed out!


    To collect the resulting hashes in another hash, you need a key (a string)
    together with each hash. How do you extract that?

    Otherwise, the best you can do is an array of hashes, one for each line
    read.

    > I need some direction on how to build the "return" hash from the file
    > contents.


    There are lots of possibilities. Which one is best would depend on details
    of your data structure that you haven't disclosed.

    Supposing there are functions get_hash and get_key which extract the
    hash and the key from each line, this builds the super-hash (untested):

    my %super;
    %{ $super{ get_key( $_)}} = get_hash( $_) while <INPUT>;

    Anno
     
    Anno Siegel, Jul 18, 2004
    #2
    1. Advertising

  3. "Anno Siegel" <-berlin.de> wrote in message
    news:cde3nv$2n$-Berlin.DE...
    > Aaron DeLoach <> wrote in comp.lang.perl.misc:
    > > Hi All,
    > >
    > > I have a file that contains either a hash, or a HoH on each line.

    >
    > A text file doesn't contain hashes, it contains text. How do you extract
    > a hash (of hashes) from each line?


    I create the hash from different data into a 'string' representation of a
    hash and write it to the file. I extract them using the 'eval' function on
    each line of the text file.

    >
    > That some of the hashes are actually hashes of hashes makes no essential
    > difference.


    I didn't think it did. However, when trying to create a 'main' hash of the
    hashes (eval-ed strings) in the text file I need a 'key' name from the hash
    name. That's where the problem lies (I think).

    >
    > > I am
    > > creating sub that will read the file and return ONE hash containing all

    the
    > > other hashes (as sub-hashes?). This way I can access each of the
    > > hashes/HoH's "through" the returned hash. Whew... I'm all hashed out!

    >
    > To collect the resulting hashes in another hash, you need a key (a string)
    > together with each hash. How do you extract that?


    ?..

    >
    > Otherwise, the best you can do is an array of hashes, one for each line
    > read.


    That's whats created when I grep the file contents. Now i want to creata a
    'main' hash containing each of the other hashes.

    >
    > > I need some direction on how to build the "return" hash from the file
    > > contents.

    >
    > There are lots of possibilities. Which one is best would depend on

    details
    > of your data structure that you haven't disclosed.
    >
    > Supposing there are functions get_hash and get_key which extract the
    > hash and the key from each line, this builds the super-hash (untested):
    >
    > my %super;
    > %{ $super{ get_key( $_)}} = get_hash( $_) while <INPUT>;


    I don't understand (forgive me).

    Aaron
     
    Aaron DeLoach, Jul 18, 2004
    #3
  4. "Michal Wojciechowski" <> wrote in message
    news:...
    > "Aaron DeLoach" <> writes:
    >
    > [...]
    >
    > > I need some direction on how to build the "return" hash from the
    > > file contents.

    >
    > See 'perldoc perldsc' for examples on HoH's and more sophisticated
    > data structures. It includes an example of reading the file contents
    > into a HoH that you could possibly adapt to your needs.


    There are also great examples in the Programming Perl book I use. But I
    still don't know how to creata a hash of existing hashes.
    >
    > HTH,
    > --
    > Michal Wojciechowski : for(<>){/\s/,$l{$m=$`}=$'}$_ : 10 PRINT "Yet

    another"
    > odyniec()odyniec;net : =$l{$c},/O\s/?$c=$'-1:y/"//d : 20 PRINT "Perl

    hacker"
    > http://odyniec.net : ,/T\s/?print$':0while$c++<$m : 30 GOTO 10
     
    Aaron DeLoach, Jul 18, 2004
    #4
  5. Aaron DeLoach

    Bob Walton Guest

    Aaron DeLoach wrote:

    > "Michal Wojciechowski" <> wrote in message
    > news:...
    >
    >>"Aaron DeLoach" <> writes:

    ....


    > There are also great examples in the Programming Perl book I use. But I
    > still don't know how to creata a hash of existing hashes.



    Well, assuming you have your "line hash" in %linehash, then you can put
    a reference to that hash as the value of a "big hash" as follows:

    $bighash{'line'.$.}=\%linehash;

    Make sure you wipe out %linehash prior to processing every line, or you
    will end up with references to *the same hash* in every element of
    %bighash. One way to do that would be like:

    use strict;
    use warnings;
    my %bighash;
    while(<DATA>){
    my %linehash;
    %linehash=eval $_;
    $bighash{'line'.$.}=\%linehash;
    }
    use Data::Dumper;
    print Dumper(\%bighash);
    __END__
    %linehash=(key1=>'value1',key2=>'value2');
    %linehash=(key3=>'value3',key4=>'value4');
    %linehash=(key5=>'value5',key6=>'value6');
    %linehash=(key7=>'value7',key8=>'value8',key9=>'value9');

    Of course, with keys like those in %bighash, one could better use an array.


    ....


    >>--
    >>Michal Wojciechowski ...

    ....

    --
    Bob Walton
    Email: http://bwalton.com/cgi-bin/emailbob.pl
     
    Bob Walton, Jul 19, 2004
    #5
  6. Aaron DeLoach

    Anno Siegel Guest

    Aaron DeLoach <> wrote in comp.lang.perl.misc:
    >
    > "Anno Siegel" <-berlin.de> wrote in message
    > news:cde3nv$2n$-Berlin.DE...
    > > Aaron DeLoach <> wrote in comp.lang.perl.misc:
    > > > Hi All,
    > > >
    > > > I have a file that contains either a hash, or a HoH on each line.

    > >
    > > A text file doesn't contain hashes, it contains text. How do you extract
    > > a hash (of hashes) from each line?

    >
    > I create the hash from different data into a 'string' representation of a
    > hash and write it to the file. I extract them using the 'eval' function on
    > each line of the text file.


    Aha.

    > > That some of the hashes are actually hashes of hashes makes no essential
    > > difference.

    >
    > I didn't think it did. However, when trying to create a 'main' hash of the
    > hashes (eval-ed strings) in the text file I need a 'key' name from the hash
    > name. That's where the problem lies (I think).


    Yes, that's what I'm getting at a few lines below.

    > > > creating sub that will read the file and return ONE hash containing all

    > the
    > > > other hashes (as sub-hashes?). This way I can access each of the
    > > > hashes/HoH's "through" the returned hash. Whew... I'm all hashed out!

    > >
    > > To collect the resulting hashes in another hash, you need a key (a string)
    > > together with each hash. How do you extract that?

    >
    > ?..


    To store a value in a hash, you need a key to store it under. You
    mentioned that yourself, but never said where the key is coming from.

    > > Otherwise, the best you can do is an array of hashes, one for each line
    > > read.

    >
    > That's whats created when I grep the file contents. Now i want to creata a
    > 'main' hash containing each of the other hashes.


    The first question you must answer for that is, where is the key
    coming from.

    > > > I need some direction on how to build the "return" hash from the file
    > > > contents.

    > >
    > > There are lots of possibilities. Which one is best would depend on

    > details
    > > of your data structure that you haven't disclosed.
    > >
    > > Supposing there are functions get_hash and get_key which extract the
    > > hash and the key from each line, this builds the super-hash (untested):
    > >
    > > my %super;
    > > %{ $super{ get_key( $_)}} = get_hash( $_) while <INPUT>;

    >
    > I don't understand (forgive me).


    Two essential features of your plan were unspecified: How to get the
    (individual) hashes from each line, and how to get the key under which
    to store it in the "super hash". So I just assumed there were routines
    "get_hash" and "get_key" to extract them. Given those, the code
    above should build the hash %super.

    The "get_hash" routine can now be made more concrete:

    sub get_hash { eval shift }

    The "get_key" routine must still be filled in, you have not said where
    the key is coming from.

    Anno
     
    Anno Siegel, Jul 19, 2004
    #6
  7. Aaron DeLoach

    Guest

    "Aaron DeLoach" <> wrote:

    > I didn't think it did. However, when trying to create a 'main' hash of
    > the hashes (eval-ed strings) in the text file I need a 'key' name from
    > the hash name. That's where the problem lies (I think).


    Yes, that is where the problem lies. But how can we help you with that
    problem? If you don't know what you want to call these hashes, how are
    we supposed to know?

    > >
    > > Otherwise, the best you can do is an array of hashes, one for each line
    > > read.

    >
    > That's whats created when I grep the file contents. Now i want to creata
    > a 'main' hash containing each of the other hashes.


    If you don't know what you want to call each hash, what makes you think
    you need to store them in a hash?

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
     
    , Jul 19, 2004
    #7
  8. "Anno Siegel" <-berlin.de> wrote in message
    news:cdftm8$29s$-Berlin.DE...
    > Aaron DeLoach <> wrote in comp.lang.perl.misc:
    > >
    > > "Anno Siegel" <-berlin.de> wrote in message
    > > news:cde3nv$2n$-Berlin.DE...
    > > > Aaron DeLoach <> wrote in comp.lang.perl.misc:
    > > > > Hi All,
    > > > >
    > > > > I have a file that contains either a hash, or a HoH on each line.
    > > >
    > > > A text file doesn't contain hashes, it contains text. How do you

    extract
    > > > a hash (of hashes) from each line?

    > >
    > > I create the hash from different data into a 'string' representation of

    a
    > > hash and write it to the file. I extract them using the 'eval' function

    on
    > > each line of the text file.

    >
    > Aha.
    >
    > > > That some of the hashes are actually hashes of hashes makes no

    essential
    > > > difference.

    > >
    > > I didn't think it did. However, when trying to create a 'main' hash of

    the
    > > hashes (eval-ed strings) in the text file I need a 'key' name from the

    hash
    > > name. That's where the problem lies (I think).

    >
    > Yes, that's what I'm getting at a few lines below.
    >
    > > > > creating sub that will read the file and return ONE hash containing

    all
    > > the
    > > > > other hashes (as sub-hashes?). This way I can access each of the
    > > > > hashes/HoH's "through" the returned hash. Whew... I'm all hashed

    out!
    > > >
    > > > To collect the resulting hashes in another hash, you need a key (a

    string)
    > > > together with each hash. How do you extract that?

    > >
    > > ?..

    >
    > To store a value in a hash, you need a key to store it under. You
    > mentioned that yourself, but never said where the key is coming from.


    I would like the key to be the hash name being extracted from the test file.

    >
    > > > Otherwise, the best you can do is an array of hashes, one for each

    line
    > > > read.

    > >
    > > That's whats created when I grep the file contents. Now i want to creata

    a
    > > 'main' hash containing each of the other hashes.

    >
    > The first question you must answer for that is, where is the key
    > coming from.


    I guess my question should have been phrased differently. It doesn't matter
    where the hashes are coming from. The problem now verified was the fact that
    a key name was needed.

    What I wanted to achieve was the ability to create a 'main hash'
    *containing* other hashes or HoH's - where the name of the hash being
    incorporated into the 'main' hash was the hash name itself. For example:

    File contains:
    %hash1.....
    %HoH...
    %hash2...

    ONE "Main" hash built from file:
    %Main=(%hash1...%HoH...%hash2...);

    The file containing the hashes is being built 'on the fly' by other
    resources. I do not have prior knowledgs of how many, or the names thereof
    the hashes inside.

    With a function that would grep/eval/whatever the text file into a "main"
    hash, I would be able to determine the names of the hashes incorporated by
    looping through the outer keys.

    The object is to (1) create the "main" hash; (2) destroy the original file;
    (3) manipulate the "main" hash/sub-hashes; (4) rebuild the text file to
    return to the original source.

    I don't know if there is a better, or more efficient way of doing it?

    >
    > > > > I need some direction on how to build the "return" hash from the

    file
    > > > > contents.
    > > >
    > > > There are lots of possibilities. Which one is best would depend on

    > > details
    > > > of your data structure that you haven't disclosed.
    > > >
    > > > Supposing there are functions get_hash and get_key which extract the
    > > > hash and the key from each line, this builds the super-hash

    (untested):
    > > >
    > > > my %super;
    > > > %{ $super{ get_key( $_)}} = get_hash( $_) while <INPUT>;

    > >
    > > I don't understand (forgive me).

    >
    > Two essential features of your plan were unspecified: How to get the
    > (individual) hashes from each line, and how to get the key under which
    > to store it in the "super hash". So I just assumed there were routines
    > "get_hash" and "get_key" to extract them. Given those, the code
    > above should build the hash %super.
    >
    > The "get_hash" routine can now be made more concrete:
    >
    > sub get_hash { eval shift }
    >
    > The "get_key" routine must still be filled in, you have not said where
    > the key is coming from.
    >
    > Anno
     
    Aaron DeLoach, Jul 20, 2004
    #8
  9. Aaron DeLoach

    Anno Siegel Guest

    Aaron DeLoach <> wrote in comp.lang.perl.misc:
    >
    > "Anno Siegel" <-berlin.de> wrote in message
    > news:cdftm8$29s$-Berlin.DE...
    > > Aaron DeLoach <> wrote in comp.lang.perl.misc:


    > > To store a value in a hash, you need a key to store it under. You
    > > mentioned that yourself, but never said where the key is coming from.

    >
    > I would like the key to be the hash name being extracted from the test file.


    I think it's time you showed us a sample of the input lines (those that
    are given to eval() to produce a hash).

    > > > > Otherwise, the best you can do is an array of hashes, one for each

    > line
    > > > > read.
    > > >
    > > > That's whats created when I grep the file contents. Now i want to creata

    > a
    > > > 'main' hash containing each of the other hashes.

    > >
    > > The first question you must answer for that is, where is the key
    > > coming from.

    >
    > I guess my question should have been phrased differently. It doesn't matter
    > where the hashes are coming from. The problem now verified was the fact that
    > a key name was needed.


    Indeed. It's the key we're talking about. You need one, and in all
    likelihood it will be extracted from the line that generates the key.

    > What I wanted to achieve was the ability to create a 'main hash'
    > *containing* other hashes or HoH's - where the name of the hash being
    > incorporated into the 'main' hash was the hash name itself. For example:
    >
    > File contains:
    > %hash1.....
    > %HoH...
    > %hash2...


    Are you saying the input file contains bits of code that assign hashes
    to program variables? Again, show us a few examples.

    If that is the case, the code in the input file is really part of the
    source code and shouldn't be executed piece-wise through eval. You
    should re-thing the design.

    > ONE "Main" hash built from file:
    > %Main=(%hash1...%HoH...%hash2...);


    A hash isn't a sequence of other things, as "(%hash1...%HoH...%hash2...)"
    would indicate. To store something in a hash you need a key, and to
    retrieve something from a hash you also need a key. That you skip
    the keys in your representation shows that you have no clear idea
    of how a hash works.

    As mentioned three or four replies back, you could build an array
    of the resulting hashes:

    @main = ( \ %hash1, \ %HoH, \ %hash2, ....);

    > The file containing the hashes is being built 'on the fly' by other
    > resources. I do not have prior knowledgs of how many, or the names thereof
    > the hashes inside.


    That's the problem with variable names that are generated at run time.
    You don't know what they are and cant access the data.

    Instead of building code that assigns to a program variable, build
    code that returns the hash without assigning it to a named variable.
    Then you can eval it and assign the result to a known place.

    > With a function that would grep/eval/whatever the text file into a "main"


    Now, "grep/eval/whatever" make strange bedfellows. Grep and eval aren't
    alternatives to accomplish the same thing.

    > hash, I would be able to determine the names of the hashes incorporated by
    > looping through the outer keys.


    You seem to hope the key names will magically appear once you have
    the "main hash". It's the other way 'round. Before you can build
    the main hash, you need a method to *assign* keys to each of the
    partial hashes.

    Anno
     
    Anno Siegel, Jul 20, 2004
    #9
  10. On 2004-07-20, Aaron DeLoach <> wrote:
    >
    > What I wanted to achieve was the ability to create a 'main hash'
    > *containing* other hashes or HoH's - where the name of the hash being
    > incorporated into the 'main' hash was the hash name itself. For example:


    I presume your file actually looks something like this:

    %hash1 = (key => 'value', key2 => 'value');
    %hash2 = (key => 'value', subhash => {key => 'value', key2 => 'value'});
    %hash3 = (key => 'value');

    and so on. That is, the file is actually Perl code that creates the
    hashes in the current package.

    If so, you could always change to a different package and extract the
    hashes from that package, something like this:

    my $code = join "", <FILE>;

    eval "package _temppkg; no strict 'vars'; $code";
    die if $@;

    my %mainhash;
    foreach my $name (keys %_temppkg::) {
    my $ref = *{$_temppkg::{$name}}{HASH} or next;
    $mainhash{$name} = $ref;
    }

    (Ps. I do hope you really, *really* trust whatever it is that creates
    the input file, since you're evaluating arbitrary Perl code from it.)

    --
    Ilmari Karonen
    If replying by e-mail, please replace ".invalid" with ".net" in address.
     
    Ilmari Karonen, Jul 20, 2004
    #10
  11. "Ilmari Karonen" <> wrote in message
    news:...
    > On 2004-07-20, Aaron DeLoach <> wrote:
    > >
    > > What I wanted to achieve was the ability to create a 'main hash'
    > > *containing* other hashes or HoH's - where the name of the hash being
    > > incorporated into the 'main' hash was the hash name itself. For example:

    >
    > I presume your file actually looks something like this:
    >
    > %hash1 = (key => 'value', key2 => 'value');
    > %hash2 = (key => 'value', subhash => {key => 'value', key2 => 'value'});
    > %hash3 = (key => 'value');
    >
    > and so on. That is, the file is actually Perl code that creates the
    > hashes in the current package.


    This is correct. The file is structured exactly as your sample above.
    OurPerl code creates the data and places it within the file.

    >
    > If so, you could always change to a different package and extract the
    > hashes from that package, something like this:
    >
    > my $code = join "", <FILE>;
    >
    > eval "package _temppkg; no strict 'vars'; $code";
    > die if $@;
    >
    > my %mainhash;
    > foreach my $name (keys %_temppkg::) {
    > my $ref = *{$_temppkg::{$name}}{HASH} or next;
    > $mainhash{$name} = $ref;
    > }


    Hmmm... Never thought of that. I 'll have to experiement with this process
    as I'm not fully familliar with it.

    >
    > (Ps. I do hope you really, *really* trust whatever it is that creates
    > the input file, since you're evaluating arbitrary Perl code from it.)
    >


    It's actually created by us, just not by the specific person updating the
    information.

    > --
    > Ilmari Karonen
    > If replying by e-mail, please replace ".invalid" with ".net" in address.
     
    Aaron DeLoach, Jul 20, 2004
    #11
    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. rp
    Replies:
    1
    Views:
    581
    red floyd
    Nov 10, 2011
  2. Brian Greenfield

    HoH and MLDBM problems

    Brian Greenfield, Aug 26, 2003, in forum: Perl Misc
    Replies:
    4
    Views:
    166
    Bob Walton
    Sep 17, 2003
  3. Replies:
    1
    Views:
    122
    Gunnar Hjalmarsson
    Jan 17, 2005
  4. Replies:
    2
    Views:
    108
  5. Allan Houston

    Building HoHoH from arbitrary size arrays ?

    Allan Houston, Jul 12, 2005, in forum: Perl Misc
    Replies:
    5
    Views:
    163
    Brian McCauley
    Jul 13, 2005
Loading...

Share This Page