At the moment, I use something like this:
my %tmpHash = routineReturningHash();
my $value = $tmpHash{'someKey'};
The only thing I need is $value
, I do not need %tmpHash
itself. So I am curious to know if there is a way to avoid declaring %tmpHash
.
I tried
my $value = ${routineReturningHash()}{'someKey'};
but it doesn't work and outputs a strange error: "Can't use string ("1/256") as a HASH ref while "strict refs" in use
".
Any ideas how it could be done?
Create a hashref out of the returned list, which you can then dereference
my $value = { routineReturningHash() }->{somekey};
In what you tried, the ${ ... }
imposes the scalar context inside. From perlref (my emphasis)
2. Anywhere you'd put an identifier (or chain of identifiers) as part of a variable or subroutine name, you can replace the identifier with a BLOCK returning a reference of the correct type.
In the scalar context the hash is evaluated to a string with fraction involving buckets; not a hashref.
Update I take it that there are design reasons for returning a hash as a flat list. If that isn't the case, then the clear solution is to just return a hashref from the sub.
That also saves a data copy: When you return a hash the scalars (keys and values) need be copied, to provide a list to the caller; when you return a reference only that one scalar is returned.
As for performance benefits ... if you can see a difference, you either have massive hashes which should be handled by reference anyway, or too many function calls what may need refactoring.
To return by reference you can
form and work with a hash in the sub and then return \%hash;
form a hashref directly return { key => 'value', ... };
If you have a big hash to work with, pass its reference and work with that
sub work_by_ref {
my ($hr) = @_;
$hr->{key} = 'value';
return 1;
}
my %hash;
work_by_ref(\%hash);
say "$_ => $hash{$_}" for sort keys %hash;
Be careful with this C-style approach; it is not all that usual in Perl to directly change caller's data. If you only need to fill a hash in the sub then build it there and return \%hash;