Froze rails gems
[depot.git] / vendor / rails / activesupport / lib / active_support / core_ext / hash / indifferent_access.rb
1 # This class has dubious semantics and we only have it so that
2 # people can write params[:key] instead of params['key']
3 # and they get the same value for both keys.
4
5 class HashWithIndifferentAccess < Hash
6 def initialize(constructor = {})
7 if constructor.is_a?(Hash)
8 super()
9 update(constructor)
10 else
11 super(constructor)
12 end
13 end
14
15 def default(key = nil)
16 if key.is_a?(Symbol) && include?(key = key.to_s)
17 self[key]
18 else
19 super
20 end
21 end
22
23 alias_method :regular_writer, :[]= unless method_defined?(:regular_writer)
24 alias_method :regular_update, :update unless method_defined?(:regular_update)
25
26 # Assigns a new value to the hash:
27 #
28 # hash = HashWithIndifferentAccess.new
29 # hash[:key] = "value"
30 #
31 def []=(key, value)
32 regular_writer(convert_key(key), convert_value(value))
33 end
34
35 # Updates the instantized hash with values from the second:
36 #
37 # hash_1 = HashWithIndifferentAccess.new
38 # hash_1[:key] = "value"
39 #
40 # hash_2 = HashWithIndifferentAccess.new
41 # hash_2[:key] = "New Value!"
42 #
43 # hash_1.update(hash_2) # => {"key"=>"New Value!"}
44 #
45 def update(other_hash)
46 other_hash.each_pair { |key, value| regular_writer(convert_key(key), convert_value(value)) }
47 self
48 end
49
50 alias_method :merge!, :update
51
52 # Checks the hash for a key matching the argument passed in:
53 #
54 # hash = HashWithIndifferentAccess.new
55 # hash["key"] = "value"
56 # hash.key? :key # => true
57 # hash.key? "key" # => true
58 #
59 def key?(key)
60 super(convert_key(key))
61 end
62
63 alias_method :include?, :key?
64 alias_method :has_key?, :key?
65 alias_method :member?, :key?
66
67 # Fetches the value for the specified key, same as doing hash[key]
68 def fetch(key, *extras)
69 super(convert_key(key), *extras)
70 end
71
72 # Returns an array of the values at the specified indices:
73 #
74 # hash = HashWithIndifferentAccess.new
75 # hash[:a] = "x"
76 # hash[:b] = "y"
77 # hash.values_at("a", "b") # => ["x", "y"]
78 #
79 def values_at(*indices)
80 indices.collect {|key| self[convert_key(key)]}
81 end
82
83 # Returns an exact copy of the hash.
84 def dup
85 HashWithIndifferentAccess.new(self)
86 end
87
88 # Merges the instantized and the specified hashes together, giving precedence to the values from the second hash
89 # Does not overwrite the existing hash.
90 def merge(hash)
91 self.dup.update(hash)
92 end
93
94 # Removes a specified key from the hash.
95 def delete(key)
96 super(convert_key(key))
97 end
98
99 def stringify_keys!; self end
100 def symbolize_keys!; self end
101 def to_options!; self end
102
103 # Convert to a Hash with String keys.
104 def to_hash
105 Hash.new(default).merge(self)
106 end
107
108 protected
109 def convert_key(key)
110 key.kind_of?(Symbol) ? key.to_s : key
111 end
112
113 def convert_value(value)
114 case value
115 when Hash
116 value.with_indifferent_access
117 when Array
118 value.collect { |e| e.is_a?(Hash) ? e.with_indifferent_access : e }
119 else
120 value
121 end
122 end
123 end
124
125 module ActiveSupport #:nodoc:
126 module CoreExtensions #:nodoc:
127 module Hash #:nodoc:
128 module IndifferentAccess #:nodoc:
129 def with_indifferent_access
130 hash = HashWithIndifferentAccess.new(self)
131 hash.default = self.default
132 hash
133 end
134 end
135 end
136 end
137 end