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”).