my %hash = ( all => 'old' ); # simple hash value
foo(\%hash); # pass reference to hash
sub foo { # recieve reference aliased as $_[0
+]
my $ref = shift; # copy reference to $ref (and throw
+ away the $_[0] alias)
$ref = { all => 'new' }; # overwrite the copy of $ref
# this creates a *new* hash and a n
+ew reference in $ref
# %hash is not modified
}
In the second version you're overwriting a key in the hash pointed to by the reference:
my %hash = ( all => 'old' ); # simple hash value
foo(\%hash); # pass reference to hash
sub foo { # recieve reference as $_[0]
my $ref = shift; # copy reference to $ref (and throw
+ away $_[0])
$ref->{ all } = 'new'; # overwrite the value to the key 'a
+ll'
# in the hash pointed to by $ref (w
+hich is %hash)
}
The key concept is that a reference only points to a value (under the hood, a reference in perl contains only slightly more information than the memory address of the data structure it's referring to) - it does not "contain" the value itself - so modifying the reference does not change the value it's pointing to - you can use it to modify the referenced data only as long as it's actually pointing to that data.
update: by the way: the fact that parameters to a function are aliased in @_ means you *can* change parameters even without passing them by reference (by assigning to $_[0] et al), but that will a) only work if the parameters are non-constant scalars, b) confuse the heck out of your coworkers.
updated code: diotalevi's right.
|