views:

60

answers:

1

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?

+4  A: 

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
DVK
Tied or not, returning a ref for big data structures might be advisable anyway (a copy could be expensive).
Thilo
@Thilo - True, although sometimes you WANT a copy, e.g. when you pass the data to multiple places where it's not guaranteed to remain constant. E.g. a list which will be used as a stack in some algorithm. Speed of copying is of course a valid consideration, just remember that it needs to be looked at in full context ;)
DVK
Agreed. But in this case, the original copy will just fall out of scope and get garbage collected. And then there is also the case where you pass the data to multiple places and want to see the changes that they do.
Thilo
I don't particularly care about efficiency here. I'm just using it in command-line arg processing. Also, aren't tied variables slow no matter what?
Ryan Thompson
"Also, aren't tied variables slow no matter what?" - correct... I think both Thilo and I were discussing returning hash by value/reference independenyly of tying, at least I was :)
DVK