【问题标题】:Hash with indifferent access具有无关访问的哈希
【发布时间】:2012-05-28 07:22:52
【问题描述】:

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

config = YAML::load(File.open("#{LOG_ROOT}/config/database.yml"))

我只能像config["host"]config["username"] 等那样访问这个哈希。

我想要无所谓的访问权限,因此我可以同时使用 :host"host"

原因是,我要传递此哈希的项目中的其中一个 gem 似乎正在使用符号访问它,但目前它失败了。

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

【问题讨论】:

  • 即使你不使用 Rails,你有什么理由不能require 'active_support/core_ext/hash/indifferent_access',还有你的解决方案吗?
  • 我还没有安装 active_support gem,我想知道我是否应该安装它只是为了获得这个功能。
  • 如果您不想这样做,请将代码复制/粘贴到您自己的哈希中,并使用无关的访问类。没看过Rails的解决方案,之前自己写过,不能超过50 LOC。
  • 我也想过这个。。在这里查看是否有更好的方法。
  • 我是 ruby​​ 新手,所以我想为什么不向社区咨询一下,以防我遗漏了什么。我愿意复制。

标签: ruby


【解决方案1】:

通过安装 Active Support gem,您只会损失几 kB 的磁盘空间。在您的代码中,您只需要所需的功能:

require 'active_support/core_ext/hash/indifferent_access'

这样,您就可以确保不会有任何其他东西弄乱您的命名空间。

【讨论】:

  • 是的,但是这样的事情会中断 :( -- "%{version}" % {version: 5}.with_indifferent_access.to_hash 因为我猜测内部使用的是字符串而不是符号 :(
  • 有趣的观察。你实际上教了我一个我在这里甚至都不知道的技巧:-),我明白了,它确实不适用于那些 ActiveSupport 无关的哈希。在短时间内,我无法说这是否可以补救,但如果您向 ActiveSupport 开发人员提交具有此效果的票,您将为 Ruby 社区做一件好事。
【解决方案2】:

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

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 每次在哈希中找不到密钥时都会运行。请注意,这只是冷漠访问的一半:如果存在密钥 :hostconfig["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

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

【讨论】:

  • 这将适用于通过[] 访问,但不适用于delete 之类的东西,您必须提供正确版本的密钥。让您知道。
  • 还要注意,它不会阻止某人添加两个键:'host' 和 :host 分配了不同的值!如果你的 Hash 中有 key 'host' 并添加 key :host 第二个不会覆盖第一个!
猜你喜欢
  • 2014-05-06
  • 1970-01-01
  • 2013-02-08
  • 2013-06-06
  • 2012-12-30
  • 2013-10-11
  • 2023-03-31
  • 1970-01-01
  • 2013-03-22
相关资源
最近更新 更多