Search code examples
perlhash

Perl - New Hash item with modified data, sourced from a feeder hash that sourced another entry, clobbers the first entry


I'm trying to add a hash entry and a new, updated hash entry that are sourced from the same feeder hash and original data.

However, when I update the data for the 2nd entry... it clobbers the original entry... even though that data wasn't changed... it can only have changed due to both being assigned from the same feeder hash entry.

Here's a sample subroutine from a test program that I created to test this issue - it uses Tk for output...

sub hash_issue {
    my %feeder = ();
    my %global = ();
    my %personal = ();

    my $key = 'John';
    my $new_key = 'Johnathan';

    $feeder{$key}{First_Name} = 'John';
    $feeder{$key}{Last_Name} = '';
    $feeder{$key}{Address} = '123 Main Street';
    $feeder{$key}{City} = 'Springfield';
    $feeder{$key}{State} = '';
    $feeder{$key}{Zip} = '';
    $feeder{$key}{Is_Registered} = 0;
    
    $global{$key} = $feeder{$key};
    $main->Output->Append("First Name = $global{$key}{First_Name}  Last Name = $global{$key}{Last_Name}  Address = $global{$key}{Address}  Registered = $global{$key}{Is_Registered}\r\n");
    $global{$new_key} = $feeder{$key};
    $global{$new_key}{First_Name} = $new_key;
    $global{$new_key}{Is_Registered} = 1;
    $main->Output->Append("First Name = $global{$key}{First_Name}  Last Name = $global{$key}{Last_Name}  Address = $global{$key}{Address}  Registered = $global{$key}{Is_Registered}\r\n");
    $main->Output->Append("First Name = $global{$new_key}{First_Name}  Last Name = $global{$new_key}{Last_Name}  Address = $global{$new_key}{Address}  Registered = $global{$new_key}{Is_Registered}\r\n");
}

Here's the output...

First Name = John Last Name = Address = 123 Main Street Registered = 0

First Name = Johnathan Last Name = Address = 123 Main Street Registered = 1

First Name = Johnathan Last Name = Address = 123 Main Street Registered = 1

(Extra Lines added to clean the post...)

How can I modify this to keep from clobbering the original entry... The REAL code contains more key to the sub hash.


Solution

  • Your problem is here

    $global{$new_key} = $feeder{$key};
    

    This only copies a reference. You need to clone your data if you want an actual copy.

    use Clone qw( clone );
    $global{$new_key} = clone( $feeder{$key} );