Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 138 lines (117 sloc) 3.725 kb
b4a1718 @jeremy Convert hash extension modules to class reopens
jeremy authored
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
0bd668f @jeremy Namespace HashWithIndifferentAccess
jeremy authored
5 module ActiveSupport
6 class HashWithIndifferentAccess < Hash
7 def initialize(constructor = {})
8 if constructor.is_a?(Hash)
9 super()
10 update(constructor)
11 else
12 super(constructor)
13 end
b4a1718 @jeremy Convert hash extension modules to class reopens
jeremy authored
14 end
15
0bd668f @jeremy Namespace HashWithIndifferentAccess
jeremy authored
16 def default(key = nil)
17 if key.is_a?(Symbol) && include?(key = key.to_s)
18 self[key]
19 else
20 super
21 end
b4a1718 @jeremy Convert hash extension modules to class reopens
jeremy authored
22 end
23
0bd668f @jeremy Namespace HashWithIndifferentAccess
jeremy authored
24 alias_method :regular_writer, :[]= unless method_defined?(:regular_writer)
25 alias_method :regular_update, :update unless method_defined?(:regular_update)
b4a1718 @jeremy Convert hash extension modules to class reopens
jeremy authored
26
0bd668f @jeremy Namespace HashWithIndifferentAccess
jeremy authored
27 # Assigns a new value to the hash:
28 #
29 # hash = HashWithIndifferentAccess.new
30 # hash[:key] = "value"
31 #
32 def []=(key, value)
33 regular_writer(convert_key(key), convert_value(value))
34 end
b4a1718 @jeremy Convert hash extension modules to class reopens
jeremy authored
35
0bd668f @jeremy Namespace HashWithIndifferentAccess
jeremy authored
36 # Updates the instantized hash with values from the second:
37 #
38 # hash_1 = HashWithIndifferentAccess.new
39 # hash_1[:key] = "value"
40 #
41 # hash_2 = HashWithIndifferentAccess.new
42 # hash_2[:key] = "New Value!"
43 #
44 # hash_1.update(hash_2) # => {"key"=>"New Value!"}
45 #
46 def update(other_hash)
47 other_hash.each_pair { |key, value| regular_writer(convert_key(key), convert_value(value)) }
48 self
49 end
b4a1718 @jeremy Convert hash extension modules to class reopens
jeremy authored
50
0bd668f @jeremy Namespace HashWithIndifferentAccess
jeremy authored
51 alias_method :merge!, :update
52
53 # Checks the hash for a key matching the argument passed in:
54 #
55 # hash = HashWithIndifferentAccess.new
56 # hash["key"] = "value"
57 # hash.key? :key # => true
58 # hash.key? "key" # => true
59 #
60 def key?(key)
61 super(convert_key(key))
62 end
b4a1718 @jeremy Convert hash extension modules to class reopens
jeremy authored
63
0bd668f @jeremy Namespace HashWithIndifferentAccess
jeremy authored
64 alias_method :include?, :key?
65 alias_method :has_key?, :key?
66 alias_method :member?, :key?
b4a1718 @jeremy Convert hash extension modules to class reopens
jeremy authored
67
0bd668f @jeremy Namespace HashWithIndifferentAccess
jeremy authored
68 # Fetches the value for the specified key, same as doing hash[key]
69 def fetch(key, *extras)
70 super(convert_key(key), *extras)
71 end
b4a1718 @jeremy Convert hash extension modules to class reopens
jeremy authored
72
0bd668f @jeremy Namespace HashWithIndifferentAccess
jeremy authored
73 # Returns an array of the values at the specified indices:
74 #
75 # hash = HashWithIndifferentAccess.new
76 # hash[:a] = "x"
77 # hash[:b] = "y"
78 # hash.values_at("a", "b") # => ["x", "y"]
79 #
80 def values_at(*indices)
81 indices.collect {|key| self[convert_key(key)]}
82 end
b4a1718 @jeremy Convert hash extension modules to class reopens
jeremy authored
83
0bd668f @jeremy Namespace HashWithIndifferentAccess
jeremy authored
84 # Returns an exact copy of the hash.
85 def dup
86 HashWithIndifferentAccess.new(self)
87 end
b4a1718 @jeremy Convert hash extension modules to class reopens
jeremy authored
88
0bd668f @jeremy Namespace HashWithIndifferentAccess
jeremy authored
89 # Merges the instantized and the specified hashes together, giving precedence to the values from the second hash
90 # Does not overwrite the existing hash.
91 def merge(hash)
92 self.dup.update(hash)
93 end
b4a1718 @jeremy Convert hash extension modules to class reopens
jeremy authored
94
0bd668f @jeremy Namespace HashWithIndifferentAccess
jeremy authored
95 # Performs the opposite of merge, with the keys and values from the first hash taking precedence over the second.
96 # This overloaded definition prevents returning a regular hash, if reverse_merge is called on a HashWithDifferentAccess.
97 def reverse_merge(other_hash)
98 super other_hash.with_indifferent_access
99 end
b4a1718 @jeremy Convert hash extension modules to class reopens
jeremy authored
100
0920e69 @methodmissing ActiveSupport Hash optimizations [#2902 state:resolved]
methodmissing authored
101 def reverse_merge!(other_hash)
102 replace(reverse_merge( other_hash ))
103 end
104
0bd668f @jeremy Namespace HashWithIndifferentAccess
jeremy authored
105 # Removes a specified key from the hash.
106 def delete(key)
107 super(convert_key(key))
108 end
b4a1718 @jeremy Convert hash extension modules to class reopens
jeremy authored
109
0bd668f @jeremy Namespace HashWithIndifferentAccess
jeremy authored
110 def stringify_keys!; self end
111 def symbolize_keys!; self end
112 def to_options!; self end
b4a1718 @jeremy Convert hash extension modules to class reopens
jeremy authored
113
0bd668f @jeremy Namespace HashWithIndifferentAccess
jeremy authored
114 # Convert to a Hash with String keys.
115 def to_hash
0920e69 @methodmissing ActiveSupport Hash optimizations [#2902 state:resolved]
methodmissing authored
116 Hash.new(default).merge!(self)
b4a1718 @jeremy Convert hash extension modules to class reopens
jeremy authored
117 end
118
0bd668f @jeremy Namespace HashWithIndifferentAccess
jeremy authored
119 protected
120 def convert_key(key)
121 key.kind_of?(Symbol) ? key.to_s : key
b4a1718 @jeremy Convert hash extension modules to class reopens
jeremy authored
122 end
0bd668f @jeremy Namespace HashWithIndifferentAccess
jeremy authored
123
124 def convert_value(value)
125 case value
126 when Hash
127 value.with_indifferent_access
128 when Array
129 value.collect { |e| e.is_a?(Hash) ? e.with_indifferent_access : e }
130 else
131 value
132 end
133 end
134 end
b4a1718 @jeremy Convert hash extension modules to class reopens
jeremy authored
135 end
0bd668f @jeremy Namespace HashWithIndifferentAccess
jeremy authored
136
137 HashWithIndifferentAccess = ActiveSupport::HashWithIndifferentAccess
Something went wrong with that request. Please try again.