Ruby has support for autovivification for hashes by passing a block to Hash.new:
hash = Hash.new { |h, k| h[k] = 42 }
hash[:foo] += 1 # => 43
I'd like to implement autovivification for structs, also. This is the best I can come up with:
Foo = Struct.new(:bar) do
def bar
self[:bar] ||= 42
end
end
foo = Foo.new
foo.bar += 1 # => 43
and of course, this only autovivifies the named accessor (foo.bar), not the [] form (foo[:bar]). Is there a better way to implement autovivification for structs, in particular one that works robustly for both the foo.bar and foo[:bar] forms?
I would go with the following approach:
foo.barabove callsfoo[:bar]under the hood throughmethod_missingmagic, so the only thing to overwrite is aStruct#[]method.Prepending a module makes it more robust, per-instance and in general more flexible.
The code above is just an example. To copy the behavior of
Hash#default_procone might (credits to @Stefan for comments):Now
default_proclambda will receive anameto decide how to behave in such a case.