Этот фрагмент кода заполняет хэш @options
. values
- это Array
, который содержит ноль или более разнородных элементов. Если вы вызываете populate
с аргументами, которые являются Hash
записями, он использует значение, указанное вами для каждой записи, чтобы принять значение по умолчанию.
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
должна измениться, чтобы приспособиться к какой-то рекурсивной версии. Нет предела количеству вложений, которое теоретически может произойти.
Есть мысли о том, как я могу это осуществить?