module Hashie::Extensions::IndifferentAccess

IndifferentAccess gives you the ability to not care whether your hash has string or symbol keys. Made famous in Rails for accessing query and POST parameters, this is a handy tool for making sure your hash has maximum utility.

One unique feature of this mixin is that it will recursively inject itself into sub-hash instances without modifying the actual class of the sub-hash.

@example

class MyHash < Hash
  include Hashie::Extensions::MergeInitializer
  include Hashie::Extensions::IndifferentAccess
end

h = MyHash.new(:foo => 'bar', 'baz' => 'blip')
h['foo'] # => 'bar'
h[:foo]  # => 'bar'
h[:baz]  # => 'blip'
h['baz'] # => 'blip'

Public Class Methods

[](*) click to toggle source
Calls superclass method
# File lib/hashie/extensions/indifferent_access.rb, line 41
def [](*)
  super.convert!
end
included(base) click to toggle source
# File lib/hashie/extensions/indifferent_access.rb, line 26
def self.included(base)
  base.class_eval do
    alias_method :regular_writer, :[]=
    alias_method :[]=, :indifferent_writer
    alias_method :store, :indifferent_writer
    %w(default update replace fetch delete key? values_at).each do |m|
      alias_method "regular_#{m}", m
      alias_method m, "indifferent_#{m}"
    end

    %w(include? member? has_key?).each do |key_alias|
      alias_method key_alias, :indifferent_key?
    end

    class << self
      def [](*)
        super.convert!
      end

      def try_convert(*)
        (hash = super) && self[hash]
      end
    end
  end
end
inject(hash) click to toggle source

Injects indifferent access into a duplicate of the hash provided. See inject!

# File lib/hashie/extensions/indifferent_access.rb, line 62
def self.inject(hash)
  inject!(hash.dup)
end
inject!(hash) click to toggle source

This will inject indifferent access into an instance of a hash without modifying the actual class. This is what allows IndifferentAccess to spread to sub-hashes.

# File lib/hashie/extensions/indifferent_access.rb, line 55
def self.inject!(hash)
  (class << hash; self; end).send :include, IndifferentAccess
  hash.convert!
end
try_convert(*) click to toggle source
Calls superclass method
# File lib/hashie/extensions/indifferent_access.rb, line 45
def try_convert(*)
  (hash = super) && self[hash]
end

Public Instance Methods

convert!() click to toggle source

Iterates through the keys and values, reconverting them to their proper indifferent state. Used when IndifferentAccess is injecting itself into member hashes.

# File lib/hashie/extensions/indifferent_access.rb, line 73
def convert!
  keys.each do |k|
    regular_writer convert_key(k), convert_value(regular_delete(k))
  end
  self
end
convert_key(key) click to toggle source
# File lib/hashie/extensions/indifferent_access.rb, line 66
def convert_key(key)
  key.to_s
end
convert_value(value) click to toggle source
# File lib/hashie/extensions/indifferent_access.rb, line 80
def convert_value(value)
  if hash_lacking_indifference?(value)
    IndifferentAccess.inject(value.dup)
  elsif value.is_a?(::Array)
    value.dup.replace(value.map { |e| convert_value(e) })
  else
    value
  end
end
indifferent_access?() click to toggle source
# File lib/hashie/extensions/indifferent_access.rb, line 122
def indifferent_access?
  true
end
indifferent_default(key = nil) click to toggle source
# File lib/hashie/extensions/indifferent_access.rb, line 90
def indifferent_default(key = nil)
  return self[convert_key(key)] if key?(key)
  regular_default(key)
end
indifferent_delete(key) click to toggle source
# File lib/hashie/extensions/indifferent_access.rb, line 110
def indifferent_delete(key)
  regular_delete convert_key(key)
end
indifferent_fetch(key, *args) click to toggle source
# File lib/hashie/extensions/indifferent_access.rb, line 106
def indifferent_fetch(key, *args)
  regular_fetch convert_key(key), *args
end
indifferent_key?(key) click to toggle source
# File lib/hashie/extensions/indifferent_access.rb, line 114
def indifferent_key?(key)
  regular_key? convert_key(key)
end
indifferent_replace(other_hash) click to toggle source
# File lib/hashie/extensions/indifferent_access.rb, line 126
def indifferent_replace(other_hash)
  (keys - other_hash.keys).each { |key| delete(key) }
  other_hash.each { |key, value| self[key] = value }
  self
end
indifferent_update(other_hash) click to toggle source
# File lib/hashie/extensions/indifferent_access.rb, line 95
def indifferent_update(other_hash)
  return regular_update(other_hash) if hash_with_indifference?(other_hash)
  other_hash.each_pair do |k, v|
    self[k] = v
  end
end
indifferent_values_at(*indices) click to toggle source
# File lib/hashie/extensions/indifferent_access.rb, line 118
def indifferent_values_at(*indices)
  indices.map { |i| self[i] }
end
indifferent_writer(key, value) click to toggle source
# File lib/hashie/extensions/indifferent_access.rb, line 102
def indifferent_writer(key, value)
  regular_writer convert_key(key), convert_value(value)
end

Protected Instance Methods

hash_lacking_indifference?(other) click to toggle source
# File lib/hashie/extensions/indifferent_access.rb, line 134
def hash_lacking_indifference?(other)
  other.is_a?(::Hash) &&
  !(other.respond_to?(:indifferent_access?) &&
    other.indifferent_access?)
end
hash_with_indifference?(other) click to toggle source
# File lib/hashie/extensions/indifferent_access.rb, line 140
def hash_with_indifference?(other)
  other.is_a?(::Hash) &&
  other.respond_to?(:indifferent_access?) &&
  other.indifferent_access?
end