這段代碼填充@options
散列。 values
是一個Array
其中包含零個或多個異構項目。如果您調用populate
的參數爲Hash
條目,它將使用您爲每個條目指定的值假定默認值。如何從提供的參數中遞歸地定義Ruby中的哈希值?
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)其鍵爲符號(或兩者的某種組合)組成的數組,則它們應被視爲子項而不是與該關鍵字相關的值,並且用於評估原始參數的相同邏輯應遞歸重新應用。
這有點難以表達出來,所以我寫了一些測試用例。下面是一些測試用例和@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
簽名需要改變以適應某種遞歸版本。理論上可以發生的嵌套量沒有限制。
任何想法如何我可以把它關閉?