Hashing References
Problem
When you use keys
on a hash whose keys are
references, the references that keys
returns no
longer work. This situation often arises when you want to
cross-reference two different hashes.
Solution
Use Tie::RefHash:
use Tie::RefHash; tie %hash, "Tie::RefHash"; # you may now use references as the keys to %hash
Discussion
Hash keys are automatically “stringified,” that is, treated as though they appeared between double quotes. In the case of numbers or strings, nothing is lost. This isn’t the case with references, though.
Stringified references look like these:
Class::Somewhere=HASH(0x72048)
ARRAY(0x72048)
A stringified reference can’t be dereferenced, because it is just a string and no longer a reference. This means you can’t use references as the keys to a hash without losing their “magic.”
Hand-rolled solutions to this problem involve maintaining a distinct hash whose keys are stringified references and whose values are the actual references. This is what Tie::RefHash does. We’ll use IO objects for filehandles here to show you that even such strange references can be used to index a hash tied with Tie::RefHash.
Here’s an example:
use Tie::RefHash; use IO::File; tie %name, "Tie::RefHash"; foreach $filename ("/etc/termcap", "/vmunix", "/bin/cat") { $fh = IO::File->new("< $filename") or next; $name{$fh} = $filename; } print "open files: ", join(", ", values %name), "\n"; foreach $file (keys %name) { seek($file, 0, 2); # seek to the end printf("%s is %d bytes long.\n", ...
Get Perl Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.