This piece of code fills the hash @options. valuesis Arraythat contains zero or more dissimilar elements. If you call populatewith arguments Hash, they use the value specified for each entry to accept the default value.
def populate(*args)
args.each do |a|
values = nil
if (a.kind_of? Hash)
a, values = a.to_a.first
end
@options[:"#{a}"] ||= values ||= {}
end
end
What I would like to do is change populateso that it recursively populates @options. There is a special case: if the values that it is going to fill in with a key are an array consisting entirely of (1) characters or (2) hashes whose keys are characters (or some combination of two), then they should be considered as subkeys, and not the values associated with this key, and the same logic used to evaluate the original arguments populatemust be recursively repeated.
It was a little hard to put into words, so I wrote some test cases. Below are some test cases and the expected value @options:
populate :a
=> @options is {:a => {}}
populate :a => 42
=> @options is {:a => 42}
populate :a, :b, :c
=> @options is {:a => {}, :b => {}, :c => {}}
populate :a, :b => "apples", :c
=> @options is {:a => {}, :b => "apples", :c => {}}
populate :a => :b
=> @options is {:a => :b}
populate :a => [:b]
=> @options is {:a => {:b => {}}}
populate :a => [:b, :c => :d]
=> @options is {:a => {:b => {}, :c => :d}}
populate :a => [:a, :b, :c]
=> @options is {:a => {:a => {}, :b => {}, :c => {}}}
populate :a => [:a, :b, "c"]
=> @options is {:a => [:a, :b, "c"]}
populate :a => [:one], :b => [:two, :three => "four"]
=> @options is {:a => :one, :b => {:two => {}, :three => "four"}}
populate :a => [:one], :b => [:two => {:four => :five}, :three => "four"]
=> @options is {:a => :one,
:b => {
:two => {
:four => :five
}
},
:three => "four"
}
}
, populate , - . , .
, ?