mrguy123 has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks
I have created an object that needs to store 2 hashes that point to the same referenced hash. The idea is that I want to store a "clean" and dirty "version" in the object.
The problem is, that the object uses the same pointer for both hashes, meaning that if I change the dirty hash, the clean hash is also changed. This is the code:
sub new { my ($class, $hash) = @_; my $this = {}; bless($this, $class); $this->{clean} = $hash; $this->{dirty} = \%orig_graph; print Dumper $this; die (0); return $this; }
If I print it (using the dumper) I get:
$VAR1 = bless( { 'dirty' => { 'a' => 1, 'b' => 2 }, 'clean' => $VAR1->{'dirty'} }, 'Edges' );
As you can see, clean points to dirty, so I can't change one without the other.
My question is, what can I do to store two versions like I want. I can go over all the keys in the hash and create a new hash, but I was wondering if there was something smarter, a bit like a copy constructer? Any ideas?
Thanks,
MrGuy


I can't complain, but sometimes I still do."
-- Joe Walsh

Thanks for all your help!
I used clone for a deep copy, and managed to fix my problem
Thanks again
Mrguy

Replies are listed 'Best First'.
Re: Using the same hashes as different object variables
by JavaFan (Canon) on Jan 20, 2010 at 12:24 UTC
    Your code doesn't show what %orig_graph is, but I assume you're calling new as ->new(\%orig_graph).

    The problem is, you now have two references to the same data. You'd need to copy the data. Perhaps deep-copy the data, but that will depend on your requirements. Copying a hash is trivial:

    my %copy = %original;
    To make a deep copy, use Data::Dumper (with Purity = 1) and eval the result.
      Thanks for your reply
      I think I do need a deep copy (my original hash also has arrays inside).
      Can you give me a bit more info on how to use the Data:Dumper for a deep copy? I usually just use it for displaying a hash

        You could also use dclone() from Storable to make a deep copy of your data.

        my $hash = eval Data::Dumper->new([{foo => 1, bar => 2}])->Purity(1)->Dump;
Re: Using the same hashes as different object variables
by cdarke (Prior) on Jan 20, 2010 at 13:17 UTC
    For a deep copy
    use Storable qw(dclone); my $copy = dclone($original);
    Storable is a base module.
Re: Using the same hashes as different object variables
by BioLion (Curate) on Jan 20, 2010 at 13:06 UTC

    If memory is an issue and having two deep copies (clean and dirty) is not great, maybe Tie::Hash::Layered could be useful, depending on whether you want the dirty or clean layer to be 'top'...

    Otherwise you could keep the dirty as a hash slice, and have methods to see whether a 'dirty' version of the data exists and if not use the 'clean' as default. An interesting problem... Let us know how you get on!

    Just a something something...
Re: Using the same hashes as different object variables
by ack (Deacon) on Jan 20, 2010 at 16:34 UTC

    I'm curious. You say you want

    "...2 hashes that point to the same referenced hash."

    Using the references approach does exactly that...both point to exact same entity so they are both just aliases for the same thing.

    I think that is not exactly what you wanted, just inadvertantly maybe described it wrong? Looks like what you want are two hashes...a working hash and a default hash (my alternative words, of course, not the OP's) and that you want to ensure that if the working hash isn't proper or gets messed up, then you want to reset it (in essence) to the default, "clean" version?

    Looking at the various response (and to your response to at least one of the respnoses) it seems that everyone understood what you were trying to do. I wasn't as insightful and headed off on the wrong track (my fault, not the OP's).

    ack Albuquerque, NM