Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 155 lines (130 sloc) 4.16 kB
19cecc9 @spastorino HWIA relies on Hash#symbolize_keys and #stringify_keys extensions.
spastorino authored
1 require 'active_support/core_ext/hash/keys'
2
b4a1718 @jeremy Convert hash extension modules to class reopens
jeremy authored
3 # This class has dubious semantics and we only have it so that
9b96de6 @suchasurge Some style changes
suchasurge authored
4 # people can write <tt>params[:key]</tt> instead of <tt>params['key']</tt>
b4a1718 @jeremy Convert hash extension modules to class reopens
jeremy authored
5 # and they get the same value for both keys.
6
0bd668f @jeremy Namespace HashWithIndifferentAccess
jeremy authored
7 module ActiveSupport
8 class HashWithIndifferentAccess < Hash
a24a888 @wycats Limit Array#extract_options! to directl instances of Hash and HWIA. A…
wycats authored
9 def extractable_options?
10 true
11 end
12
0bd668f @jeremy Namespace HashWithIndifferentAccess
jeremy authored
13 def initialize(constructor = {})
14 if constructor.is_a?(Hash)
15 super()
16 update(constructor)
17 else
18 super(constructor)
19 end
b4a1718 @jeremy Convert hash extension modules to class reopens
jeremy authored
20 end
21
0bd668f @jeremy Namespace HashWithIndifferentAccess
jeremy authored
22 def default(key = nil)
23 if key.is_a?(Symbol) && include?(key = key.to_s)
24 self[key]
25 else
26 super
27 end
b4a1718 @jeremy Convert hash extension modules to class reopens
jeremy authored
28 end
29
eab4860 @fxn avoids a ton o warnings activesupport/lib/active_support/dependencies…
fxn authored
30 def self.new_from_hash_copying_default(hash)
02039e9 @laserlemon Ensure that HashWithIndifferentAccess duplication preserves class (fo…
laserlemon authored
31 new(hash).tap do |new_hash|
eab4860 @fxn avoids a ton o warnings activesupport/lib/active_support/dependencies…
fxn authored
32 new_hash.default = hash.default
33 end
34 end
35
0bd668f @jeremy Namespace HashWithIndifferentAccess
jeremy authored
36 alias_method :regular_writer, :[]= unless method_defined?(:regular_writer)
37 alias_method :regular_update, :update unless method_defined?(:regular_update)
b4a1718 @jeremy Convert hash extension modules to class reopens
jeremy authored
38
0bd668f @jeremy Namespace HashWithIndifferentAccess
jeremy authored
39 # Assigns a new value to the hash:
40 #
41 # hash = HashWithIndifferentAccess.new
42 # hash[:key] = "value"
43 #
44 def []=(key, value)
45 regular_writer(convert_key(key), convert_value(value))
46 end
b4a1718 @jeremy Convert hash extension modules to class reopens
jeremy authored
47
d80afed @andreacampi Override #store to be consistent with #[].
andreacampi authored
48 alias_method :store, :[]=
49
0bd668f @jeremy Namespace HashWithIndifferentAccess
jeremy authored
50 # Updates the instantized hash with values from the second:
51 #
52 # hash_1 = HashWithIndifferentAccess.new
53 # hash_1[:key] = "value"
54 #
55 # hash_2 = HashWithIndifferentAccess.new
56 # hash_2[:key] = "New Value!"
57 #
58 # hash_1.update(hash_2) # => {"key"=>"New Value!"}
59 #
60 def update(other_hash)
61 other_hash.each_pair { |key, value| regular_writer(convert_key(key), convert_value(value)) }
62 self
63 end
b4a1718 @jeremy Convert hash extension modules to class reopens
jeremy authored
64
0bd668f @jeremy Namespace HashWithIndifferentAccess
jeremy authored
65 alias_method :merge!, :update
66
67 # Checks the hash for a key matching the argument passed in:
68 #
69 # hash = HashWithIndifferentAccess.new
70 # hash["key"] = "value"
71 # hash.key? :key # => true
72 # hash.key? "key" # => true
73 #
74 def key?(key)
75 super(convert_key(key))
76 end
b4a1718 @jeremy Convert hash extension modules to class reopens
jeremy authored
77
0bd668f @jeremy Namespace HashWithIndifferentAccess
jeremy authored
78 alias_method :include?, :key?
79 alias_method :has_key?, :key?
80 alias_method :member?, :key?
b4a1718 @jeremy Convert hash extension modules to class reopens
jeremy authored
81
0bd668f @jeremy Namespace HashWithIndifferentAccess
jeremy authored
82 # Fetches the value for the specified key, same as doing hash[key]
83 def fetch(key, *extras)
84 super(convert_key(key), *extras)
85 end
b4a1718 @jeremy Convert hash extension modules to class reopens
jeremy authored
86
0bd668f @jeremy Namespace HashWithIndifferentAccess
jeremy authored
87 # Returns an array of the values at the specified indices:
88 #
89 # hash = HashWithIndifferentAccess.new
90 # hash[:a] = "x"
91 # hash[:b] = "y"
92 # hash.values_at("a", "b") # => ["x", "y"]
93 #
94 def values_at(*indices)
95 indices.collect {|key| self[convert_key(key)]}
96 end
b4a1718 @jeremy Convert hash extension modules to class reopens
jeremy authored
97
0bd668f @jeremy Namespace HashWithIndifferentAccess
jeremy authored
98 # Returns an exact copy of the hash.
99 def dup
02039e9 @laserlemon Ensure that HashWithIndifferentAccess duplication preserves class (fo…
laserlemon authored
100 self.class.new(self).tap do |new_hash|
101 new_hash.default = default
102 end
0bd668f @jeremy Namespace HashWithIndifferentAccess
jeremy authored
103 end
b4a1718 @jeremy Convert hash extension modules to class reopens
jeremy authored
104
0bd668f @jeremy Namespace HashWithIndifferentAccess
jeremy authored
105 # Merges the instantized and the specified hashes together, giving precedence to the values from the second hash
106 # Does not overwrite the existing hash.
107 def merge(hash)
108 self.dup.update(hash)
109 end
b4a1718 @jeremy Convert hash extension modules to class reopens
jeremy authored
110
0bd668f @jeremy Namespace HashWithIndifferentAccess
jeremy authored
111 # Performs the opposite of merge, with the keys and values from the first hash taking precedence over the second.
9b96de6 @suchasurge Some style changes
suchasurge authored
112 # This overloaded definition prevents returning a regular hash, if reverse_merge is called on a <tt>HashWithDifferentAccess</tt>.
0bd668f @jeremy Namespace HashWithIndifferentAccess
jeremy authored
113 def reverse_merge(other_hash)
5914875 @fxn now for real, the suite loads everything and these went unpatched
fxn authored
114 super self.class.new_from_hash_copying_default(other_hash)
0bd668f @jeremy Namespace HashWithIndifferentAccess
jeremy authored
115 end
b4a1718 @jeremy Convert hash extension modules to class reopens
jeremy authored
116
0920e69 @methodmissing ActiveSupport Hash optimizations [#2902 state:resolved]
methodmissing authored
117 def reverse_merge!(other_hash)
118 replace(reverse_merge( other_hash ))
119 end
120
0bd668f @jeremy Namespace HashWithIndifferentAccess
jeremy authored
121 # Removes a specified key from the hash.
122 def delete(key)
123 super(convert_key(key))
124 end
b4a1718 @jeremy Convert hash extension modules to class reopens
jeremy authored
125
d692e6b @jeremy Restore HWIA#stringify_keys! and update changelog
jeremy authored
126 def stringify_keys!; self end
c976784 @jeremy Change HWIA#stringify_keys to return a HWIA not a Hash
jeremy authored
127 def stringify_keys; dup end
2472f10 @spastorino HWIA delegates to to_hash symbolize_keys and stringify_keys and bang …
spastorino authored
128 undef :symbolize_keys!
129 def symbolize_keys; to_hash.symbolize_keys end
0bd668f @jeremy Namespace HashWithIndifferentAccess
jeremy authored
130 def to_options!; self end
b4a1718 @jeremy Convert hash extension modules to class reopens
jeremy authored
131
0bd668f @jeremy Namespace HashWithIndifferentAccess
jeremy authored
132 # Convert to a Hash with String keys.
133 def to_hash
0920e69 @methodmissing ActiveSupport Hash optimizations [#2902 state:resolved]
methodmissing authored
134 Hash.new(default).merge!(self)
b4a1718 @jeremy Convert hash extension modules to class reopens
jeremy authored
135 end
136
0bd668f @jeremy Namespace HashWithIndifferentAccess
jeremy authored
137 protected
138 def convert_key(key)
139 key.kind_of?(Symbol) ? key.to_s : key
b4a1718 @jeremy Convert hash extension modules to class reopens
jeremy authored
140 end
0bd668f @jeremy Namespace HashWithIndifferentAccess
jeremy authored
141
142 def convert_value(value)
099eb2b @dlee indifferent access should recurse Hash subclasses
dlee authored
143 if value.is_a? Hash
144 value.nested_under_indifferent_access
ce9456e @josevalim Only convert direct hash instances in hash with indifferent access.
josevalim authored
145 elsif value.is_a?(Array)
146 value.dup.replace(value.map { |e| convert_value(e) })
0bd668f @jeremy Namespace HashWithIndifferentAccess
jeremy authored
147 else
148 value
149 end
150 end
151 end
b4a1718 @jeremy Convert hash extension modules to class reopens
jeremy authored
152 end
0bd668f @jeremy Namespace HashWithIndifferentAccess
jeremy authored
153
154 HashWithIndifferentAccess = ActiveSupport::HashWithIndifferentAccess
Something went wrong with that request. Please try again.