Autovivification in Ruby

Came up recently on #ruby-lang: this fellow wanted to perform Perl-style autovivification in Ruby. Well, no, Ruby doesn’t do it implicitly, but you can get it if that’s what you want.

Namely:

Perl: push @{$somehash{'foo'}}, 'bar';

Ruby: (somehash['foo'] ||= []).push 'bar'

The ||= Operator

For those not familiar, the ||= operator will perform assignment iff its LHS is false. As a result, these two Ruby snippets are equivalent:

var = 'foo' unless var

and:

var ||= 'foo'

(It really comes in handy when the LHS is a complex expression.)

Another sort of situation where it would come in handy:


stuff = nil
somecollection.each do |thing|
  if thing.relevent?
    stuff ||= []
    stuff += thing.stuff
  end
end
if stuff # there were relevent things
  if stuff.empty? # no stuff though
    ...
  else # yay, they had stuff
    ...
  end
else # no relevent things
  ...
end

Trivia: the ||= operator was actually borrowed from Perl, but it’s not very widely used there. Partly because autovivification is the default, and partly because Perl considers empty strings and 0 to be false (so you can’t use it to distinguish “undef”).