References and Nested Data
Shallow Copy and Mutation
Assigning a reference shares the same data, while copying a hash makes a separate top-level hash.
shallow copy
A shallow copy duplicates the top-level container but not deeper nested values.
Shallow Copy and Mutation
shallow_copy_mutation.pl
Replay: real traced execution (multi-file project)
use strict;
use warnings;
my $new_status = "done";
my $original_ref = { status => "open" };
my $alias_ref = $original_ref;
my $copy_ref = { %{$original_ref} };
$alias_ref->{status} = $new_status;
my $original_status = $original_ref->{status};
my $copy_status = $copy_ref->{status};
print "new_status=$new_status\n";
print "original=$original_status\n";
print "copy=$copy_status\n";
use strict;
use warnings;
my $new_status = "hold";
my $original_ref = { status => "open" };
my $alias_ref = $original_ref;
my $copy_ref = { %{$original_ref} };
$alias_ref->{status} = $new_status;
my $original_status = $original_ref->{status};
my $copy_status = $copy_ref->{status};
print "new_status=$new_status\n";
print "original=$original_status\n";
print "copy=$copy_status\n";
use strict;
use warnings;
my $new_status = "ready";
my $original_ref = { status => "open" };
my $alias_ref = $original_ref;
my $copy_ref = { %{$original_ref} };
$alias_ref->{status} = $new_status;
my $original_status = $original_ref->{status};
my $copy_status = $copy_ref->{status};
print "new_status=$new_status\n";
print "original=$original_status\n";
print "copy=$copy_status\n";
$new_status ← done, $original_status ← done, $copy_status ← open
4my $new_status→ done = "done"; #@new_status="hold", "ready"5my $original_ref = { status => "open" };6my $alias_ref = $original_ref;7my $copy_ref = { %{$original_ref} };89$alias_ref->{status} = $new_statusdone;1011my $original_status→ done = $original_ref->{status};12my $copy_status→ open = $copy_ref->{status};1314print "new_status=$new_statusdone\n";15print "original=$original_statusdone\n";16print "copy=$copy_statusopen\n";outputnew_status=done original=done copy=open
$new_status ← hold, $original_status ← hold, $copy_status ← open
4my $new_status→ hold = "hold";5my $original_ref = { status => "open" };6my $alias_ref = $original_ref;7my $copy_ref = { %{$original_ref} };89$alias_ref->{status} = $new_statushold;1011my $original_status→ hold = $original_ref->{status};12my $copy_status→ open = $copy_ref->{status};1314print "new_status=$new_statushold\n";15print "original=$original_statushold\n";16print "copy=$copy_statusopen\n";outputnew_status=hold original=hold copy=open
$new_status ← ready, $original_status ← ready, $copy_status ← open
4my $new_status→ ready = "ready";5my $original_ref = { status => "open" };6my $alias_ref = $original_ref;7my $copy_ref = { %{$original_ref} };89$alias_ref->{status} = $new_statusready;1011my $original_status→ ready = $original_ref->{status};12my $copy_status→ open = $copy_ref->{status};1314print "new_status=$new_statusready\n";15print "original=$original_statusready\n";16print "copy=$copy_statusopen\n";outputnew_status=ready original=ready copy=open