哈希与漠不关心的访问

Jos*_*hin 30 ruby

我有一个非Rails项目,我在其中从YAML文件加载一些设置:

config = YAML::load(File.open("#{LOG_ROOT}/config/database.yml"))
Run Code Online (Sandbox Code Playgroud)

我只能访问这个哈希一样config["host"],config["username"]等等.

我想要无所谓的访问,所以我可以使用:host"host".

原因是,我传递此哈希的项目中的一个gem似乎是使用符号访问它,它当前失败了.

在这种情况下,创建具有无差别访问权限的哈希的最佳方法是什么?

Bor*_*cky 51

除了几KB的磁盘空间外,通过安装Active Support gem,您几乎不会丢失任何内容.在您的代码中,您只需要您想要的功能:

require 'active_support/core_ext/hash/indifferent_access'
Run Code Online (Sandbox Code Playgroud)

这样,你可以确定你没有得到任何其他东西来搞乱你的命名空间.


ste*_*lag 19

让配置哈希返回键的字符串化版本的值:

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"
Run Code Online (Sandbox Code Playgroud)

default_proc每次当钥匙不在哈希中运行.请注意,这只是无关紧要的访问的一半:config["host"]如果密钥:host存在,将导致nil .如果这也必须工作:

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
Run Code Online (Sandbox Code Playgroud)

请参阅有关此方法的限制的评论(tltr:单独的值:a'a'可能的,不考虑Hash.delete和其他).

  • 这将通过`[]`进行访问,但不适用于`delete`这样的东西,你必须提供正确的密钥版本.只是你知道. (10认同)
  • 另请注意,它不会阻止某人添加两个键:'host'和:分配了不同值的主机!如果你的哈希中有密钥'host'并添加密钥:host第二个不会覆盖第一个! (3认同)