http://www.perlmonks.org?node_id=501734

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

Here is my situation: I'm inside a method. I access a local variable (a hash ref), munge the hash and then return my munged data. The problem comes in that I seem to be munging my member variable as well. I need to work with a local copy so that the member variable is uncorrupted. Here is my current (broken) code:
my $aref = $self->{atlas}; my %atlas = %$aref; ... munging ...
What do I need to do to make manipulating %atlas non-destructive to $self->{atlas} ?

Thanks!

Replies are listed 'Best First'.
Re: Local Copy of a member variable
by Roy Johnson (Monsignor) on Oct 20, 2005 at 17:08 UTC
    You'll need a deep copy. See Data::COW. Update: Or, as holli suggests below, Scalar::Util::Clone. The former will do actual copies only of things you change; the latter will copy everything, but fast. So if it's a big structure that you're only modifying a little of, use Data::COW; if you're going to modify a substantial portion of it, use Scalar::Util::Clone.

    Caution: Contents may have been coded under pressure.
Re: Local Copy of a member variable
by TedYoung (Deacon) on Oct 20, 2005 at 17:09 UTC

    If it is a simple hash then changes to %atlas won't be seen in $self->{atlas}. Now, if the values of $self->{atlas} contain references (i.e. other hashes, arrays, object, etc) then changes to those will be seen. If you need to make a deep copy (clone) of a complex datastructure, you could use dclone method is Storable.

    use Storable; my $aref = dclone($self->{atlas}); my %atlas = %$aref;

    Ted Young

    ($$<<$$=>$$<=>$$<=$$>>$$) always returns 1. :-)
      From the docs of Storable:
      There is a Clone module available on CPAN which implements deep cloning natively, i.e. without freezing to memory and thawing the result.
      So I'd recomment Clone or Scalar::Util::Clone. There is also Clone::Any which is an interface for the existing clonecapable modules.

      Of course, Storable has the advantage that you can save your structures to disk (including code references).


      holli, /regexed monk/
Re: Local Copy of a member variable
by jeffa (Bishop) on Oct 20, 2005 at 17:06 UTC

    Try this instead

    my $atlas_copy = { %$atlas };
    UPDATE: but a deep copy is the better choice here. I was assuming you were dealing with a simple hash structure and i failed to notice that you were copying to hash, not a hash ref. Nothing to see here ... move along. bad jeffa :)

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)