2012-05-28 105 views
24

我有一個非Rails項目中,我從一個YAML文件中加載一些設置:哈希與冷漠訪問

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

我只能訪問這個散列像config["host"]config["username"]

我想要無所謂的訪問,所以我可以使用:host"host"

原因是,我通過這個散列項目中的一個寶石似乎是使用符號訪問它,它目前失敗。

在這種情況下創建一個無差別訪問哈希的最佳方式是什麼?

+10

沒有任何理由,爲什麼你就是不'要求「active_support/core_ext /散列/ indifferent_access'',並有你的解決方案? – Casper

+2

我還沒有安裝active_support gem,想知道我是否應該安裝它才能獲得此功能。 – Josnidhin

+0

如果你不想要,將代碼複製/粘貼到你自己的哈希與無差別訪問類。我沒有看過Rails的解決方案,但我自己寫過一個,不能超過50 LOC。 –

回答

15

讓配置哈希返回值的鍵的字符串化版本:

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每次運行時的關鍵並不在散找到。注意這只是無關訪問的一半:如果密鑰:host存在,則config["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 
+8

這可以通過'[]'進行訪問,但不適用於像'delete'這樣的事情,你必須提供正確版本的 – iain

+2

請注意,它不會阻止某人添加兩個密鑰:'主機'和:具有不同值的主機!如果您的密鑰'主機'在您的哈希中並添加密鑰:主機第二個不會覆蓋th第一個! – wrzasa

42

通過安裝Active Support gem,您幾乎不會損失幾kB磁盤空間。在代碼中,你只需要你想要的功能:

require 'active_support/core_ext/hash/indifferent_access' 

這樣的話,你可以確保你沒有得到任何東西弄亂你的命名空間。

+1

是的,但然後這樣的事情打破:( - 「%{版本}」%{版本:5} .with_indifferent_access.to_hash因爲我在內部猜測字符串使用,而不是符號:( –

+0

有趣的觀察。我是一個我在這裏不知道的技巧:-),而且我看到,它確實不適用於那些ActiveSupport冷漠的哈希。在短時間內,我無法說這是否可以補救,但是你會做一個如果你想向ActiveSupport開發者提交一個票據到這個效果的話,那麼你可以爲Ruby社區做好事。 –