Complicated perl data structures are built up with references. That's fine
and dandy, easy to pass around etc. etc. But in the passing, what if you need
to make changes? Generally modifying somebody else's data structure is not
considered a nice thing to do. Well then, you could copy it. But being
reference based you'd end up with a shallow copy i.e; all the internal
references would be the same and you'd still by changing somebody else's data.
Well then, you could try to minimize the scope of what you touch with
my or local but that can be really messy and error prone,
especially if you don't know what you'll be touching or others didn't
plan on you putting your grubby paws all over everything. So, what to do? Enter
Data::COW.
MoooooOOO
COW stands for Copy On Write, and is implemented exactly how you would expect.
In fact, the implementation is a lot like object inheritance. You give the COW
a reference and it returns the favor. You then proceed to use this new
reference in the same manner as you would have the original but are free to
maul it at will, or not... PETA might get mad. To begin with, fetching data
from the referenced data structure simply gets the value from the parent
because the child doesn't "implement the method". When you store, or change,
a value in the structure that change is only made to your child structure and
these modifications will be used when fetching values in the future instead of
accessing the parent. Perhaps an example will help...
$struct = {
'b1f' => 'I like meat!',
'fib' => [
1,
1,
2,
3
]
};
Make changes here...
$calf = {
'fib' => [
'1',
'1',
'2',
'3',
'5',
'8',
'13'
],
'b1f' => 'I like meat!'
};
$struct = {
'b1f' => 'I like meat!',
'fib' => [
1,
1,
2,
3
]
};
$calf = {
'fib' => [
'1',
'1',
'2',
'3',
'5',
'8',
'13'
],
'b1f' => 'I like meat!'
};
Eat more chickin
And now, on with the code!
1 use Data::COW;
2 use Data::Dumper; #No jokes about buffalo biscuits please
3
4 my $struct = {
5 fib=>[1,1,2,3],
6 b1f=>'I like meat!'
7 };
8
9 print Data::Dumper->Dump([$struct], ['struct']);
10
11 print "Make changes here...\n";
12 my $calf = make_cow_ref $struct;
13 push @{$calf->{fib}}, 5, 8, 13;
14
15 print Data::Dumper->Dump([$calf], ['calf']);
16
17
18 print Data::Dumper->Dump([$struct, $calf], [qw'struct calf']);
19
20 #Okay fine, but a deep copy would look the same...
21 #...but references would be different, even for unmodified values
22 print "Eat more chickin\n" if $struct->{b1f} eq $calf->{b1f};
See Also
Clone