Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Perl, how can I return a tied hash from a subroutine?

I want to have a perl subroutine that creates and returns an ordered hash via the Tie::IxHash module. It looks something like this:

sub make_ordered_hash {
    my @hash_contents = munge_input(@_); # I get a list of alternating keys and values
    tie(my %myhash, Tie::IxHash, @hash_contents);
    return %myhash;
}

Now, if I do my %ordered_hash = make_ordered_hash(@input_stuff), will %ordered_hash actually be tied, or will it unpack %myhash, into a list and then create a new (ordinary, unordered) hash from that list? If I can't return a tied hash in this way, can I return a reference to one? That is, can I fix it by having make_ordered_hash return \%myhash instead?

like image 304
Ryan C. Thompson Avatar asked Oct 28 '10 23:10

Ryan C. Thompson


1 Answers

No. What you return when you do that is a COPY of the hash contents, and that copy is NOT tied, just as you surmised in the second paragraph.

You are also correct in that to achieve you result, you need to return a refernce to a tied hash instead: return \%myhash;

Example

use Tie::IxHash;

sub make_ordered_hash {
    my @hash_contents = (1,11,5,15,3,13);
    tie(my %myhash, Tie::IxHash, @hash_contents);
    return %myhash;
}
sub make_ordered_hashref {
    my @hash_contents = (1,11,5,15,3,13);
    tie(my %myhash, Tie::IxHash, @hash_contents);
    return \%myhash;
}

my @keys;

my %hash1 = make_ordered_hash();
@keys = keys %hash1;
print "By Value = @keys\n";

my $hash2 = make_ordered_hashref();
@keys = keys %$hash2;
print "By Reference = @keys\n";

Result:

By Value = 1 3 5
By Reference = 1 5 3
like image 179
DVK Avatar answered Oct 08 '22 12:10

DVK