Stok Footage

Continually experimenting with new ideas and techniques — Reconstructing, Developing, Modernising.

“Autovivifying” Ruby Hashes (another code nugget)

I often found Perl’s “autovivification” of intermediate levels of a nested hash useful, particularly in quick and dirty scripts were defining a real object and access methods seemed like overkill.

Recently I noticed a post on the ruby-lang mailing list from Jesús Gabriel y Galán which showed a technique which approximates the autovivifacation in Ruby.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
ratdog:~ mike$ pry --simple-prompt
>> hash = Hash.new { |h, k| h[k] = Hash.new &h.default_proc }
=> {}
>> hash[:foo][:bar][:baz] = 'plugh'; hash
=> {
    :foo => {
        :bar => {
            :baz => "plugh"
        }
    }
}
>> hash[:foo][:baa][:bax] = 'oops'; hash
=> {
    :foo => {
        :bar => {
            :baz => "plugh"
        },
        :baa => {
            :bax => "oops"
        }
    }
}

There is a difference in behaviour between Perl and Ruby when an attempt to read a non-existent element is made. In Ruby the access will create the element as a new empty hash:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
>hash[:a][:b][:c]
=> {}
>> hash
=> {
    :foo => {
        :bar => {
            :baz => "plugh"
        },
        :baa => {
            :bax => "oops"
        }
    },
      :a => {
        :b => {
            :c => {}
        }
    }
}
>>

It’s still a good trick for my Ruby toolbox, and a good reminder to refresh my memory on the less frequently used methods on Hash.

Tags:

One Response to ““Autovivifying” Ruby Hashes (another code nugget)”

  1. Gem XKeys allows you to manage nested hashes, nested arrays, other nested structures, Perl-ish auto-vivification (on *write*, as it should be, not read), PHP-ish auto-indexing, and per-access default values.

Leave a Reply

Your email address will not be published. Required fields are marked *