Reputation: 2221
Is there any difference in doing the following, efficiency, bad practice...?
(In a context of bigger hashes and sending them through many functions)
sub function {
my ($self, $hash_ref) = @_;
my %hash = %{$hash_ref};
print $hash{$key};
return;
}
Compared to:
sub function {
my ($self, $hash_ref) = @_;
print $hash_ref->{$key};
return;
}
Upvotes: 1
Views: 131
Reputation: 66901
The first version of the sub creates a local copy of the data structure which reference is passed to it. As such it is far less efficient, of course.
There is one legitimate reason for this: to make sure the data in the caller isn't changed. That local %hash
can be changed in the sub as needed or convenient and the data in the calling code is not affected. This way the data in the caller is also protected against accidental changes.
Another reason why a local copy of data is done, in particular with deeper data structures, is to avoid long chains of dereferencing and thus simplify code; so parts of deep hierarchies may be copied for simpler access. Then this is merely for (presumed) programming convenience.
So in the shown example there'd be absolutely no reason to make a local copy. However, presumably the question is about subs where more work is done and then what's best depends on details.
Upvotes: 2
Reputation: 385915
Let's say %$hash_ref
contains N elements.
The first snippet does the following in addition to what the second snippet does:
The second snippet does the following in addition to what the first snippet does:
The first snippet is therefore far less efficient than the second. It also more complicated by virtue of having extra code. The complete lack of benefit and the numerous costs dictate that one should avoid the pattern used in the first snippet.
Upvotes: 2
Reputation: 687
1st snippet is silly. But it's convenient practice to emulate named arguments:
sub function {
my ($self, %params ) = @_;
...
}
So, pass arrays/hashes by reference, creation of new (especially big) hash will be much slower. But there is nothing bad in "named arguments" hack.
And did you now that there exist key/value slice (v5.20+ only)? You can copy part of hash easily this way: my %foo = ( one => 1, two => 2, three => 3, four => 4); my %bar = %foo{'one', 'four'};
More information in perldoc perldata
Upvotes: 2