in reply to Deepcopy of complex structures.

I'm writing a recursive routine that does destructive processing on a passed ref to an AoHoA... but as I return from each level of recursion, I need to 'undo' the changes made.

Basically, I need to provide a deepcopy of (or some subtree of) the structure as I recurse in so that I retain an unchanged copy as I come back up the tree.

It sounds to me as if you are all barking up the wrong tree. From the definition of your problem, it sounds like you just want to use local, to localise a copy of the data structure you are working on. When you leave the recursed scope, the data structure will resume its previously stored values, without any effort on your part.

If you need to make permanent modifications from time to time then you will have to arrange a signalling mechanism between levels, so that the parent receives the replacement of the child subtree, and does the replacement.


update for aragorn: you are free to initialise a localised variable to the value of the variable it is localising, which gets rid of that problem.

update for BrowserUk: Yes, indeed locality doesn't propagate, but can't you just localise as you go, or does that make the code too messy? Can you show an example of the data structure?

#! /usr/bin/perl -w <code> use strict; use vars qw/ $r $r2 /; $r = { foo => [ { one => 1, two => 2, three => 3 }, { four => 4, five => 5, six => 6 }, ], }; { print "orig : $r->{foo}[1]{five}\n"; $r2 = $r->{foo}; local $r2->[1]{five} = $r2->[1]{five} + 500; print "then : $r->{foo}[1]{five}\n\n"; } print "after: $r->{foo}[1]{five}\n";

Hope this helps, i.e. what I am trying to get at is that it is always nice to try and get the language to do the dirty work for you, rather than writing code in the language to achieve the same functionality.


print@_{sort keys %_},$/if%_=split//,'= & *a?b:e\f/h^h!j+n,o@o;r$s-t%t#u'

Replies are listed 'Best First'.
Re: Re: Deepcopy of complex structures.
by BrowserUk (Patriarch) on Jan 21, 2003 at 10:17 UTC

    Indeed, for simple scalars, localising a copy (or just my'ing a local copy) will take care undoing changes as the program recurses.

    However, if the scalar in question is a ref to an array or hash, localising the ref will undo any changes to the ref itself, but it won't undo any changes to the structure referenced.


    Examine what is said, not who speaks.

    The 7th Rule of perl club is -- pearl clubs are easily damaged. Use a diamond club instead.

Re: Re: Deepcopy of complex structures.
by Aragorn (Curate) on Jan 21, 2003 at 09:25 UTC
    As far as I understand the problem, BrowserUk needs to read from the "old" datastructure, so local isn't really going to help, because it gives you a nice empty variable which effectively hides the old variable and does not do a complete copy of the datastructure.

    Arjen

Re: Re: Deepcopy of complex structures.
by BrowserUk (Patriarch) on Jan 21, 2003 at 14:18 UTC

    Your right. Letting the language do it is the right way to do it. What I am doing (using Clone) is to localise subtree's of the data structure into my'd vars at any given level of recursion and then allowing perl to undo this as it unwinds. See Re: Re: Deepcopy of complex structures. for somewhat more verbose (though not necessarilly clearer explanation :)

    With regard an example of the structure. If I ever get the algorithm to work and if it works as well as I hope, I'm sure to post the code here.

    If it doesn't I'll probably keep real quiet about it:)


    Examine what is said, not who speaks.

    The 7th Rule of perl club is -- pearl clubs are easily damaged. Use a diamond club instead.