Хэш с безразличным доступом
У меня есть проект non-Rails, в котором я загружаю некоторые параметры из файла YAML:
config = YAML::load(File.open("#{LOG_ROOT}/config/database.yml"))
Я могу получить доступ только к этому хешу, например config["host"]
, config["username"]
и т.д.
Я хочу безразличный доступ, чтобы использовать как :host
, так и "host"
.
Причина в том, что один из камней в проекте, к которому я передаю этот хеш, похоже, обращается к нему с использованием символов, и в настоящее время он терпит неудачу.
Какой лучший способ создать хэш с равнодушным доступом в этом сценарии?
Ответы
Ответ 1
Пусть хэш-код конфигурации возвращает значение для строковой версии ключа:
config = {"host"=>"value1", "Username"=>"Tom"}
config.default_proc = proc{|h, k| h.key?(k.to_s) ? h[k.to_s] : nil}
p config[:host] #=> "value1"
default_proc
запускается каждый раз, когда ключ не найден в хэше. Обратите внимание, что это только половина безразличного доступа: config["host"]
приведет к нулю, если присутствует ключ :host
. Если это тоже нужно:
config.default_proc = proc do |h, k|
case k
when String then sym = k.to_sym; h[sym] if h.key?(sym)
when Symbol then str = k.to_s; h[str] if h.key?(str)
end
end
Ответ 2
Вы ничего не теряете, кроме нескольких килобайт дискового пространства, устанавливая драгоценный камень Active Support. В вашем коде вам требуется только функция, которую вы хотите:
require 'active_support/core_ext/hash/indifferent_access'
Таким образом, вы можете быть уверены, что не получаете ничего другого, чтобы испортить пространство имен.