copying hashes without references

Discussion in 'Perl Misc' started by jere@cassidyweb.com, Dec 31, 2004.

  1. Guest

    After getting a good grasp on references (or at least i thought). I ran
    into a simple problem which i cannot seem to get away from.

    I have a complex data structure of hashes / arrays that I am setting up
    before running a program. I noticed that several of the documents I
    was parsing with this program shared the same attributes. I am using
    the data structure as a guide - it tells me what to parse (and what not
    to parse). Therefore, I need an element for each page i want to
    parse, but i dont want to have to type the same attributes over and
    over again. I created a hash with the common attributes and tried to
    simply insert it into the hash. I might have several of these
    "templates", so I created a hash to store them.

    #here is hash (im going to try to insert
    # %{ $fmt_template{outsrc_1}:

    %fmt_template =
    ( 'outsrc_1' => {
    System => 'end_sides',
    DataRange => [ { R => 8, C => 0, r => 999, c => 3 },
    { R => 8, C => 5, r => 999, c => 8 } ],
    Columns => [ 'sn', 'sn_net', 'host', 'desc' ]
    }
    );


    # Here is a snippet of the array im trying to insert into:

    %format = ( 'format_e' => {
    Sheet => [
    #Sheet 0: sheet name
    { System => 'step',
    DataRange => [ { R => 2, C => 2, r => 41, c => 4 } ],
    Columns => [ 'step', 'step2', 'step3' ]
    }
    #Sheet 1-4: these sheets are all the same and share similar
    # attributes:
    %format->{'format_excel'},
    %format->{'format_excel'},
    %format->{'format_excel'},
    %format->{'format_excel'}
    ]
    }
    );

    #so im on a particular sheet and i know its number, so i do:
    #for loop for each Sheet (index via $i)
    my $Fmt = $format{'format_e'}{Sheet}[$i];

    #well, then i realized that there is one attribute that needed
    #to be adjusted between the differnt sheets
    #notice that the inserted hash has a r = 999. This represents max
    #number of rows i could have, but i need to find the specific max #rows
    of each document and compare. So i do the following:

    #$x iterates through the number of DataRange arrays each
    #Sheet[$i] contains:
    if ( $Fmt->{DataRange}[$x]->{r} > $oSheet->{MaxRow} ) {
    $Fmt->{DataRange}[$x]->{r} = $oSheet->{MaxRow};
    }

    #now ive changed the individual data range maxrow (r) element
    # not true! ive changed them all due to using references??
    # during the next for loop (next sheet) $Fmt->{DataRange}[$x]->{r}
    # = 40 (maxrow of the previous sheet). It should be 999 again.

    #Can someone point out what im doing wrong? I tried turning
    #%format into a reference using $format = { hash } notation and #then
    using {} braces arround "$format->{format_e}" in the larger
    #hash. This works sytactically, but still when i change one, i
    #change them all.

    #I thought using a reference and THEN using a dereference would
    #return a copy of each but that didnt work. I also tried just for
    #fun the following

    %format1 = %format
    %format2 = %format

    #and then tried using them in the code (references and not), but
    #that still suffered from the same problem - it all seemed to be
    #copies of the same memory location so when i changed one thing,
    #they all changed.

    #I even tried writing a small test program to test out different
    #sytnaxes until i found something that worked, but this was
    #fruitless.
     
    , Dec 31, 2004
    #1
    1. Advertising

  2. Guest

    > #here is hash (im going to try to insert
    > # %{ $fmt_template{outsrc_1}:
    >
    > %fmt_template =
    > ( 'outsrc_1' => {
    > System => 'end_sides',
    > DataRange => [ { R => 8, C => 0, r => 999, c => 3 },
    > { R => 8, C => 5, r => 999, c => 8 } ],
    > Columns => [ 'sn', 'sn_net', 'host', 'desc' ]
    > }
    > );
    >


    a hash with a single element which is a reference to hash which
    contains three elements: first contains a string, second contains an
    array reference in which there is two hash references, and third is
    another array reference with four strings in the array.

    >
    > # Here is a snippet of the array im trying to insert into:
    >
    > %format = ( 'format_e' => {
    > Sheet => [
    > #Sheet 0: sheet name
    > { System => 'step',
    > DataRange => [ { R => 2, C => 2, r => 41, c => 4 } ],
    > Columns => [ 'step', 'step2', 'step3' ]
    > }
    > #Sheet 1-4: these sheets are all the same and share similar
    > # attributes:
    > %format->{'format_excel'},
    > %format->{'format_excel'},
    > %format->{'format_excel'},
    > %format->{'format_excel'}
    > ]
    > }
    > );
    >
    > #so im on a particular sheet and i know its number, so i do:
    > #for loop for each Sheet (index via $i)
    > my $Fmt = $format{'format_e'}{Sheet}[$i];


    I think there is a problem here with how you dereference.

    my $Fmt = ${${$format{'format_e'}}{sheet}}[$i];

    or

    my $Fmt = $format{'format_e'}->{Sheet}->[$i];

    >
    > #well, then i realized that there is one attribute that needed
    > #to be adjusted between the differnt sheets
    > #notice that the inserted hash has a r = 999. This represents max
    > #number of rows i could have, but i need to find the specific max

    #rows
    > of each document and compare. So i do the following:
    >
    > #$x iterates through the number of DataRange arrays each
    > #Sheet[$i] contains:
    > if ( $Fmt->{DataRange}[$x]->{r} > $oSheet->{MaxRow} ) {
    > $Fmt->{DataRange}[$x]->{r} = $oSheet->{MaxRow};
    > }


    $Fmt->{DataRange}->[$x]->{r}

    >
    > #now ive changed the individual data range maxrow (r) element
    > # not true! ive changed them all due to using references??
    > # during the next for loop (next sheet) $Fmt->{DataRange}[$x]->{r}
    > # = 40 (maxrow of the previous sheet). It should be 999 again.
    >
    > #Can someone point out what im doing wrong? I tried turning
    > #%format into a reference using $format = { hash } notation and #then
    > using {} braces arround "$format->{format_e}" in the larger
    > #hash. This works sytactically, but still when i change one, i
    > #change them all.
    >
    > #I thought using a reference and THEN using a dereference would
    > #return a copy of each but that didnt work. I also tried just for
    > #fun the following
    >
    > %format1 = %format
    > %format2 = %format
    >
    > #and then tried using them in the code (references and not), but
    > #that still suffered from the same problem - it all seemed to be
    > #copies of the same memory location so when i changed one thing,
    > #they all changed.
    >
    > #I even tried writing a small test program to test out different
    > #sytnaxes until i found something that worked, but this was
    > #fruitless.


    I may be wrong on those, but it looks like that is the problem or part
    of the problem. It's hard to believe that you need such a complicated
    structure, but maybe you do.

    wana
     
    , Dec 31, 2004
    #2
    1. Advertising

  3. <> wrote:


    > Subject: copying hashes without references

    ^^^^
    > After getting a good grasp on references (or at least i thought). I ran
    > into a simple problem



    Perhaps someone else has run into the same problem before?

    It may even have happened so often that a pat answer has been
    written up and widely published.

    Collections of such problems, and their solutions, are known
    as FAQs (Frequently Asked Questions).

    You should consult the FAQs for a particular subject area when
    you encounter a problem in that area.

    The FAQs for Perl come with the perl distribution, they are
    sitting there on your hard drive somewhere waiting for you
    to look at them. :)


    > which i cannot seem to get away from.



    perldoc -q copy

    How do I print out or copy a recursive data structure?


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
     
    Tad McClellan, Dec 31, 2004
    #3
  4. Guest


    > Hi,
    >
    > what you do in your example is work with "shallow copies" of your
    > data. If you want to really copy the contents of a data structure
    > instead of the references it contains, this is called a "deep copy".
    > Randal L. Schwartz has written an good article for the Unix Review
    > on that topic:
    > http://www.stonehenge.com/merlyn/UnixReview/col30.html
    >
    > Also CPAN holds a bunch of cloning modules, just give "clone" as
    > search term to search.cpan.org.
    >
    > HTH
    > -Chris


    Chris,
    Thank you very much for this article! I used the FAQ ( i knew I'd
    get some RTFM or RTFFAQ replies even if i didnt) and didnt realize the
    terminology of "deep" and "shallow" copies. Also, I thought it would
    be trivial to do what I was asking --- that it was just some part of
    PERL syntax that i was missing and wasnt able to figure out. This
    article was a great resource. Thanks again!
    -Jere
     
    , Jan 3, 2005
    #4
    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. Ben Holness

    Hashes of Hashes via subs

    Ben Holness, Oct 5, 2003, in forum: Perl
    Replies:
    8
    Views:
    589
    Ben Holness
    Oct 8, 2003
  2. Steven Arnold

    using hashes as keys in hashes

    Steven Arnold, Nov 23, 2005, in forum: Ruby
    Replies:
    3
    Views:
    183
    Mauricio Fernández
    Nov 23, 2005
  3. kazaam
    Replies:
    12
    Views:
    294
    Matthias Wächter
    Sep 13, 2007
  4. Neela megha shyam Chivukula

    On Hashes - How the hashes printing works?

    Neela megha shyam Chivukula, May 27, 2009, in forum: Ruby
    Replies:
    4
    Views:
    279
    Markus Schirp
    May 28, 2009
  5. Tim O'Donovan

    Hash of hashes, of hashes, of arrays of hashes

    Tim O'Donovan, Oct 27, 2005, in forum: Perl Misc
    Replies:
    5
    Views:
    233
Loading...

Share This Page