Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the best Perl practice for returning hashes from functions?

I am mulling over a best practice for passing hash references for return data to/from functions.

On the one hand, it seems intuitive to pass only input values to a function and have only return output variables. However, passing hashes in Perl can only be done by reference, so it is a bit messy and would seem more of an opportunity to make a mistake.

The other way is to pass a reference in the input variables, but then it has to be dealt with in the function, and it may not be clear what is an input and what is a return variable.

What is a best practice regarding this?

Return references to an array and a hash, and then dereference it.

($ref_array,$ref_hash) = $this->getData('input');
@array = @{$ref_array};
%hash = %{$ref_hash};

Pass in references (@array, %hash) to the function that will hold the output data.

$this->getData('input', \@array, \%hash);
like image 825
Dan Littlejohn Avatar asked Jul 07 '09 21:07

Dan Littlejohn


2 Answers

Just return the reference. There is no need to dereference the whole hash like you are doing in your examples:

my $result = some_function_that_returns_a_hashref;
say "Foo is ", $result->{foo};
say $_, " => ", $result->{$_} for keys %$result;

etc.

I have never seen anyone pass in empty references to hold the result. This is Perl, not C.

like image 148
jrockway Avatar answered Oct 14 '22 10:10

jrockway


Trying to create copies by saying

my %hash = %{$ref_hash};

is even more dangerous than using the hashref. This is because it only creates a shallow copy. This will lead you to thinking it is okay to modify the hash, but if it contains references they will modify the original data structure. I find it better to just pass references and be careful, but if you really want to make sure you have a copy of the reference passed in you can say:

use Storable qw/dclone/;

my %hash = %{dclone $ref_hash};
like image 39
Chas. Owens Avatar answered Oct 14 '22 09:10

Chas. Owens