Wednesday, July 14, 2010

Adventures in Ignorance: Autovivification for fun and profit

Perl 5 autovivifies hashes and arrays when an undef is used as a hashref or arrayref. Normally you see this when using multidimensional data structures like this:

my %hash;
$hash{foo}{bar} = 1;

The value in $hash{foo} is undefined, so Perl 5 turns it into a hashref so it can lookup the key "bar" in it. This is somewhat dangerous because you can create keys without meaning to:

if ($hash{bar}{baz} == 1) {
say "found "bar/baz";
}

Here the key "bar" will be added to the %hash if it doesn't already exist. To prevent this we must check every level but the last with exists:

if (exists $hash{bar} and $hash{bar}{baz} == 1) {
say "found "bar/baz";
}

When I think of autovivification, that is all I normally think of, but today I realized you can use it for more than that. I have a couple of hashrefs I want to set the initial size of with keys. I was saying

my $hashref     = {};
keys(%$hashref) = 1024;

As I wrote that I wondered if autovivification would turn an undef in $hashref into a hashref for me, and sure enough it will:

#!/usr/bin/perl

use 5.012;
use warnings;

use Scalar::Util qw/reftype/;

my $hashref; #not really a hashref yet
keys(%$hashref) = 1024; #but now it is

say reftype $hashref;

No comments:

Post a Comment

Some limited HTML markup is allowed by blogger: strong, b, i, and a. You may also use em, but I have repurposed it through the magic of CSS to be behave very much like <tt><code></code></tt>.