I have a non-Rails project in which I am loading some settings from a YAML file:
config = YAML::load File.open("#{LOG_ROOT}/config/database.yml")
I can only access this hash like config["host"]
, config["username"]
etc.
I want indifferent access so I can use both :host
and "host"
.
The reason is, that one of the gems in the project to which I am passing this hash seems to be accessing it using symbols and it fails currently.
What is the best way to create a hash with indifferent access in this scenario?
Let the config hash return the value for the stringified version of the key:
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"
The default_proc
runs everytime when a key is not found in the hash. Note this is only half of indifferent access: config["host"]
will result in nil if the key :host
is present. If that has to work too:
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
See the comments about limitations of this approach (tltr: separate values for :a
and 'a'
are possible, does not take into account Hash.delete
and others).