Hash with case-insensitive, Symbol/String-indifferent key access.
gem install insensitive_hash
require 'insensitive_hash'
ih = {}.insensitive
ih = { :abc => 1, 'hello world' => true }.insensitive
ih['ABC'] # 1
ih[:Hello_World] # true
If you don't like to have Hash#insensitive method, require 'insensitive_hash/minimal'
require 'insensitive_hash/minimal'
ih = InsensitiveHash.new
ih = InsensitiveHash.new(:default_value)
ih = InsensitiveHash.new { |ih, k| ih[k] = InsensitiveHash.new }
ih = InsensitiveHash[ 'abc' => 1, :def => 2 ]
ih = InsensitiveHash[ 'abc', 1, :def, 2 ]
ih = InsensitiveHash[ [['abc', 1], [:def, 2]] ]
ih = InsensitiveHash[ 'hello world' => true ]
h = ih.sensitive
h = ih.to_hash
ih = {:abc => 1, 'DEF' => 2}.insensitive
# Case-insensitive, Symbol/String-indifferent access.
ih['Abc'] # 1
ih[:ABC] # 1
ih['abc'] # 1
ih[:abc] # 1
ih.has_key?(:DeF) # true
ih['ABC'] = 10
# keys and values
ih.keys # ['DEF', 'ABC']
ih.values # [2, 10]
# delete
ih.delete :Abc # 10
ih.keys # ['DEF']
When an InsensitiveHash is built from another Hash, descendant Hash values are recursively converted to be insensitive.
ih = { 'kids' => { :hello => [ { :world => '!!!' } ] } }.insensitive
ih[:kids]['Hello'].first['WORLD'] # !!!
ih = {:one => [ [ [ { :a => { :b => { :c => 'd' } } } ] ] ]}.insensitive
ih['one'].first.first.first['A']['b'][:C] # 'd'
However, once InsensitiveHash is initialized, descendant Hashes (or Hashes in Arrays) are not automatically converted.
ih = {}.insensitive
ih[:abc] = { :def => true }
ih['ABC']['DEF'] # nil
Simply build a new InsensitiveHash out of it if you need recursive conversion.
ih2 = ih.insensitive
ih2['ABC']['DEF'] # true
db = YAML.load(File.read 'database.yml').insensitive
# Access values however you like
db['Development']['ADAPTER']
db[:production][:adapter]
You can provide a #call
-able object (duck-typing) as the key encoder which determines the level of insensitivity.
The default encoder is as follows.
InsensitiveHash::DEFAULT_ENCODER =
proc { |key|
case key
when String, Symbol
key.to_s.downcase.gsub(' ', '_')
else
key
end
}
ih1 = {}.insensitive(:encoder => proc { |key| key.to_s })
ih2 = {}.insensitive(:encoder => proc { |key| key.to_s.downcase })
ih3 = {}.insensitive(:encoder => proc { |key| key.to_s.downcase.gsub(/\s+/, '_') })
ih = InsensitiveHash.new
ih.safe = true
# Will raise InsensitiveHash::KeyClashError
h.merge!('hello world' => 1, :hello_world => 2)
# Disables key-clash detection
h.safe = false
h.merge!('hello world' => 1, :hello_world => 2)
h['Hello World'] # 2
Copyright (c) 2013 Junegunn Choi. See LICENSE.txt for further details.