这段代码填充一个@options
哈希表。 values
是一个包含零个或多个异构项的数组
。如果你使用Hash
条目作为参数调用populate
,它将使用你指定的值作为每个条目的默认值。
def populate(*args)
args.each do |a|
values = nil
if (a.kind_of? Hash)
# Converts {:k => "v"} to `a = :k, values = "v"`
a, values = a.to_a.first
end
@options[:"#{a}"] ||= values ||= {}
end
end
我想要做的是更改
populate
函数,使其可以递归地填充@options
。有一个特殊情况:如果要填充键的值是完全由符号(1)或键为符号的哈希(2)组成的数组,则它们应该被视为子键而不是与该键关联的值,并且应该递归地重新应用原始populate
参数时使用相同的逻辑进行评估。这有点难以用语言表达,因此我编写了一些测试用例。以下是一些测试用例及
@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}
# Because [:b] is an Array consisting entirely of Symbols or
# Hashes whose keys are Symbols, we assume that :b is a subkey
# of @options[:a], rather than the value for @options[:a].
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
的签名,这是可以接受的。理论上可能会发生无限嵌套。
你对我如何实现这个有什么想法吗?