in reply to Elegantly dereferencing multiple references

Hi Anonymous,

Others have already pointed out you can just edit the hashes through the references directly, and that seems like the way to go in your case. Just to explain why your second two examples don't work: Arrays or hashes on the left hand side of a my (...) = ... assignment only make sense as the last item being assigned to, because they slurp up all the remaining values from the right hand side.

That means when you write my (%x, %y, %z) = ..., then the hash %x will slurp up all the values assigned to it:

$ perl -wMstrict -MData::Dumper -le 'my (%x,%y) = (1,2,3,4); print Dum +per(\%x,\%y)' $VAR1 = { '1' => 2, '3' => 4 }; $VAR2 = {};

Also, be aware that my %copy = %hash; only makes a shallow copy, so if %hash contains values which are references to other data, then those will reference the same data structures - which may not be what you want. If you want deep copies, Storable's dclone or Clone may be able to help you there.

And just for completeness, here's one ("elegant"?) way to make the shallow copies:

use warnings; use strict; use Data::Dump 'pp'; my %x = ("a" => "red"); my %y = ("b" => "green"); my %z = ("c" => "black"); pp \%x, \%y, \%z; my ($r1, $r2, $r3) = modfifyHash(\%x, \%y, \%z); pp $r1, $r2, $r3; pp \%x, \%y, \%z; # these remain unmodified sub modfifyHash { #my ($x, $y, $z) = @_; # this would modify the original hashes my ($x, $y, $z) = map { { %{ $_ } } } @_; # ^ ^ ^ # | | for each argument # | dereference as hash # make new hash reference (shallow copy!) $x->{a} = "circle"; $y->{b} = "square"; $z->{c} = "rectangle"; return $x, $y, $z; } __END__ ({ a => "red" }, { b => "green" }, { c => "black" }) ({ a => "circle" }, { b => "square" }, { c => "rectangle" }) ({ a => "red" }, { b => "green" }, { c => "black" })

Although I would second Eily's suggestion that it might be a good idea to combine the hashes into one.

Hope this helps,
-- Hauke D