esod-client 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. data/EXAMPLES +140 -0
  2. data/GEM_RELEASE +19 -0
  3. data/README +10 -0
  4. data/Rakefile +14 -0
  5. data/VERSION +1 -0
  6. data/esod-client.gemspec +118 -0
  7. data/esod-client.rb +35 -0
  8. data/lib/activesupport-2.2.2/CHANGELOG +1257 -0
  9. data/lib/activesupport-2.2.2/README +43 -0
  10. data/lib/activesupport-2.2.2/README.CFT +2 -0
  11. data/lib/activesupport-2.2.2/lib/active_support.rb +26 -0
  12. data/lib/activesupport-2.2.2/lib/active_support/base64.rb +33 -0
  13. data/lib/activesupport-2.2.2/lib/active_support/basic_object.rb +24 -0
  14. data/lib/activesupport-2.2.2/lib/active_support/buffered_logger.rb +122 -0
  15. data/lib/activesupport-2.2.2/lib/active_support/cache.rb +223 -0
  16. data/lib/activesupport-2.2.2/lib/active_support/cache/compressed_mem_cache_store.rb +20 -0
  17. data/lib/activesupport-2.2.2/lib/active_support/cache/drb_store.rb +15 -0
  18. data/lib/activesupport-2.2.2/lib/active_support/cache/file_store.rb +72 -0
  19. data/lib/activesupport-2.2.2/lib/active_support/cache/mem_cache_store.rb +127 -0
  20. data/lib/activesupport-2.2.2/lib/active_support/cache/memory_store.rb +52 -0
  21. data/lib/activesupport-2.2.2/lib/active_support/cache/synchronized_memory_store.rb +47 -0
  22. data/lib/activesupport-2.2.2/lib/active_support/callbacks.rb +280 -0
  23. data/lib/activesupport-2.2.2/lib/active_support/core_ext.rb +6 -0
  24. data/lib/activesupport-2.2.2/lib/active_support/core_ext/hash.rb +14 -0
  25. data/lib/activesupport-2.2.2/lib/active_support/core_ext/hash/conversions.rb +259 -0
  26. data/lib/activesupport-2.2.2/lib/active_support/core_ext/hash/deep_merge.rb +23 -0
  27. data/lib/activesupport-2.2.2/lib/active_support/core_ext/hash/diff.rb +19 -0
  28. data/lib/activesupport-2.2.2/lib/active_support/core_ext/hash/except.rb +25 -0
  29. data/lib/activesupport-2.2.2/lib/active_support/core_ext/hash/indifferent_access.rb +137 -0
  30. data/lib/activesupport-2.2.2/lib/active_support/core_ext/hash/keys.rb +52 -0
  31. data/lib/activesupport-2.2.2/lib/active_support/core_ext/hash/reverse_merge.rb +35 -0
  32. data/lib/activesupport-2.2.2/lib/active_support/core_ext/hash/slice.rb +33 -0
  33. data/lib/activesupport-2.2.2/lib/active_support/vendor.rb +14 -0
  34. data/lib/activesupport-2.2.2/lib/active_support/vendor/builder-2.1.2/blankslate.rb +113 -0
  35. data/lib/activesupport-2.2.2/lib/active_support/vendor/builder-2.1.2/builder.rb +13 -0
  36. data/lib/activesupport-2.2.2/lib/active_support/vendor/builder-2.1.2/builder/blankslate.rb +20 -0
  37. data/lib/activesupport-2.2.2/lib/active_support/vendor/builder-2.1.2/builder/css.rb +250 -0
  38. data/lib/activesupport-2.2.2/lib/active_support/vendor/builder-2.1.2/builder/xchar.rb +115 -0
  39. data/lib/activesupport-2.2.2/lib/active_support/vendor/builder-2.1.2/builder/xmlbase.rb +139 -0
  40. data/lib/activesupport-2.2.2/lib/active_support/vendor/builder-2.1.2/builder/xmlevents.rb +63 -0
  41. data/lib/activesupport-2.2.2/lib/active_support/vendor/builder-2.1.2/builder/xmlmarkup.rb +328 -0
  42. data/lib/activesupport-2.2.2/lib/active_support/vendor/xml-simple-1.0.11/xmlsimple.rb +1021 -0
  43. data/lib/activesupport-2.2.2/lib/activesupport.rb +1 -0
  44. data/lib/esodclient/esodclient.rb +22 -0
  45. data/lib/hash.rb +22 -0
  46. data/lib/mime-types-1.16/History.txt +107 -0
  47. data/lib/mime-types-1.16/Install.txt +17 -0
  48. data/lib/mime-types-1.16/Licence.txt +15 -0
  49. data/lib/mime-types-1.16/Manifest.txt +12 -0
  50. data/lib/mime-types-1.16/README.txt +28 -0
  51. data/lib/mime-types-1.16/Rakefile +316 -0
  52. data/lib/mime-types-1.16/lib/mime/types.rb +751 -0
  53. data/lib/mime-types-1.16/lib/mime/types.rb.data +1324 -0
  54. data/lib/mime-types-1.16/mime-types.gemspec +43 -0
  55. data/lib/mime-types-1.16/setup.rb +1585 -0
  56. data/lib/mime-types-1.16/test/test_mime_type.rb +356 -0
  57. data/lib/mime-types-1.16/test/test_mime_types.rb +122 -0
  58. data/lib/rest-client-1.2.0/README.rdoc +102 -0
  59. data/lib/rest-client-1.2.0/Rakefile +57 -0
  60. data/lib/rest-client-1.2.0/VERSION +1 -0
  61. data/lib/rest-client-1.2.0/bin/restclient +87 -0
  62. data/lib/rest-client-1.2.0/lib/rest_client.rb +2 -0
  63. data/lib/rest-client-1.2.0/lib/restclient.rb +108 -0
  64. data/lib/rest-client-1.2.0/lib/restclient/exceptions.rb +89 -0
  65. data/lib/rest-client-1.2.0/lib/restclient/mixin/response.rb +48 -0
  66. data/lib/rest-client-1.2.0/lib/restclient/net_http_ext.rb +21 -0
  67. data/lib/rest-client-1.2.0/lib/restclient/payload.rb +178 -0
  68. data/lib/rest-client-1.2.0/lib/restclient/raw_response.rb +30 -0
  69. data/lib/rest-client-1.2.0/lib/restclient/request.rb +287 -0
  70. data/lib/rest-client-1.2.0/lib/restclient/resource.rb +146 -0
  71. data/lib/rest-client-1.2.0/lib/restclient/response.rb +20 -0
  72. data/lib/rest-client-1.2.0/spec/base.rb +10 -0
  73. data/lib/rest-client-1.2.0/spec/exceptions_spec.rb +65 -0
  74. data/lib/rest-client-1.2.0/spec/master_shake.jpg +0 -0
  75. data/lib/rest-client-1.2.0/spec/mixin/response_spec.rb +46 -0
  76. data/lib/rest-client-1.2.0/spec/payload_spec.rb +131 -0
  77. data/lib/rest-client-1.2.0/spec/raw_response_spec.rb +17 -0
  78. data/lib/rest-client-1.2.0/spec/request_spec.rb +521 -0
  79. data/lib/rest-client-1.2.0/spec/resource_spec.rb +75 -0
  80. data/lib/rest-client-1.2.0/spec/response_spec.rb +21 -0
  81. data/lib/rest-client-1.2.0/spec/restclient_spec.rb +53 -0
  82. data/lib/trollop/trollop.rb +735 -0
  83. metadata +137 -0
@@ -0,0 +1,6 @@
1
+ # Dir[File.dirname(__FILE__) + "/core_ext/*.rb"].sort.each do |path|
2
+ # filename = File.basename(path)
3
+ # require "active_support/core_ext/#{filename}"
4
+ # end
5
+
6
+ require "active_support/core_ext/hash"
@@ -0,0 +1,14 @@
1
+ %w(keys indifferent_access deep_merge reverse_merge conversions diff slice except).each do |ext|
2
+ require "active_support/core_ext/hash/#{ext}"
3
+ end
4
+
5
+ class Hash #:nodoc:
6
+ include ActiveSupport::CoreExtensions::Hash::Keys
7
+ include ActiveSupport::CoreExtensions::Hash::IndifferentAccess
8
+ include ActiveSupport::CoreExtensions::Hash::DeepMerge
9
+ include ActiveSupport::CoreExtensions::Hash::ReverseMerge
10
+ include ActiveSupport::CoreExtensions::Hash::Conversions
11
+ include ActiveSupport::CoreExtensions::Hash::Diff
12
+ include ActiveSupport::CoreExtensions::Hash::Slice
13
+ include ActiveSupport::CoreExtensions::Hash::Except
14
+ end
@@ -0,0 +1,259 @@
1
+ require 'date'
2
+ require 'cgi'
3
+ require 'builder'
4
+ require 'xmlsimple'
5
+
6
+ # Locked down XmlSimple#xml_in_string
7
+ class XmlSimple
8
+ # Same as xml_in but doesn't try to smartly shoot itself in the foot.
9
+ def xml_in_string(string, options = nil)
10
+ handle_options('in', options)
11
+
12
+ @doc = parse(string)
13
+ result = collapse(@doc.root)
14
+
15
+ if @options['keeproot']
16
+ merge({}, @doc.root.name, result)
17
+ else
18
+ result
19
+ end
20
+ end
21
+
22
+ def self.xml_in_string(string, options = nil)
23
+ new.xml_in_string(string, options)
24
+ end
25
+ end
26
+
27
+ # This module exists to decorate files deserialized using Hash.from_xml with
28
+ # the <tt>original_filename</tt> and <tt>content_type</tt> methods.
29
+ module FileLike #:nodoc:
30
+ attr_writer :original_filename, :content_type
31
+
32
+ def original_filename
33
+ @original_filename || 'untitled'
34
+ end
35
+
36
+ def content_type
37
+ @content_type || 'application/octet-stream'
38
+ end
39
+ end
40
+
41
+ module ActiveSupport #:nodoc:
42
+ module CoreExtensions #:nodoc:
43
+ module Hash #:nodoc:
44
+ module Conversions
45
+
46
+ XML_TYPE_NAMES = {
47
+ "Symbol" => "symbol",
48
+ "Fixnum" => "integer",
49
+ "Bignum" => "integer",
50
+ "BigDecimal" => "decimal",
51
+ "Float" => "float",
52
+ "Date" => "date",
53
+ "DateTime" => "datetime",
54
+ "Time" => "datetime",
55
+ "TrueClass" => "boolean",
56
+ "FalseClass" => "boolean"
57
+ } unless defined?(XML_TYPE_NAMES)
58
+
59
+ XML_FORMATTING = {
60
+ "symbol" => Proc.new { |symbol| symbol.to_s },
61
+ "date" => Proc.new { |date| date.to_s(:db) },
62
+ "datetime" => Proc.new { |time| time.xmlschema },
63
+ "binary" => Proc.new { |binary| ActiveSupport::Base64.encode64(binary) },
64
+ "yaml" => Proc.new { |yaml| yaml.to_yaml }
65
+ } unless defined?(XML_FORMATTING)
66
+
67
+ # TODO: use Time.xmlschema instead of Time.parse;
68
+ # use regexp instead of Date.parse
69
+ unless defined?(XML_PARSING)
70
+ XML_PARSING = {
71
+ "symbol" => Proc.new { |symbol| symbol.to_sym },
72
+ "date" => Proc.new { |date| ::Date.parse(date) },
73
+ "datetime" => Proc.new { |time| ::Time.parse(time).utc rescue ::DateTime.parse(time).utc },
74
+ "integer" => Proc.new { |integer| integer.to_i },
75
+ "float" => Proc.new { |float| float.to_f },
76
+ "decimal" => Proc.new { |number| BigDecimal(number) },
77
+ "boolean" => Proc.new { |boolean| %w(1 true).include?(boolean.strip) },
78
+ "string" => Proc.new { |string| string.to_s },
79
+ "yaml" => Proc.new { |yaml| YAML::load(yaml) rescue yaml },
80
+ "base64Binary" => Proc.new { |bin| ActiveSupport::Base64.decode64(bin) },
81
+ "file" => Proc.new do |file, entity|
82
+ f = StringIO.new(ActiveSupport::Base64.decode64(file))
83
+ f.extend(FileLike)
84
+ f.original_filename = entity['name']
85
+ f.content_type = entity['content_type']
86
+ f
87
+ end
88
+ }
89
+
90
+ XML_PARSING.update(
91
+ "double" => XML_PARSING["float"],
92
+ "dateTime" => XML_PARSING["datetime"]
93
+ )
94
+ end
95
+
96
+ def self.included(klass)
97
+ klass.extend(ClassMethods)
98
+ end
99
+
100
+ # Converts a hash into a string suitable for use as a URL query string. An optional <tt>namespace</tt> can be
101
+ # passed to enclose the param names (see example below).
102
+ #
103
+ # ==== Example:
104
+ # { :name => 'David', :nationality => 'Danish' }.to_query # => "name=David&nationality=Danish"
105
+ #
106
+ # { :name => 'David', :nationality => 'Danish' }.to_query('user') # => "user%5Bname%5D=David&user%5Bnationality%5D=Danish"
107
+ def to_query(namespace = nil)
108
+ collect do |key, value|
109
+ value.to_query(namespace ? "#{namespace}[#{key}]" : key)
110
+ end.sort * '&'
111
+ end
112
+
113
+ alias_method :to_param, :to_query
114
+
115
+ def to_xml(options = {})
116
+ options[:indent] ||= 2
117
+ options.reverse_merge!({ :builder => Builder::XmlMarkup.new(:indent => options[:indent]),
118
+ :root => "hash" })
119
+ options[:builder].instruct! unless options.delete(:skip_instruct)
120
+ dasherize = !options.has_key?(:dasherize) || options[:dasherize]
121
+ root = dasherize ? options[:root].to_s.dasherize : options[:root].to_s
122
+
123
+ options[:builder].__send__(:method_missing, root) do
124
+ each do |key, value|
125
+ case value
126
+ when ::Hash
127
+ value.to_xml(options.merge({ :root => key, :skip_instruct => true }))
128
+ when ::Array
129
+ value.to_xml(options.merge({ :root => key, :children => key.to_s.singularize, :skip_instruct => true}))
130
+ when ::Method, ::Proc
131
+ # If the Method or Proc takes two arguments, then
132
+ # pass the suggested child element name. This is
133
+ # used if the Method or Proc will be operating over
134
+ # multiple records and needs to create an containing
135
+ # element that will contain the objects being
136
+ # serialized.
137
+ if 1 == value.arity
138
+ value.call(options.merge({ :root => key, :skip_instruct => true }))
139
+ else
140
+ value.call(options.merge({ :root => key, :skip_instruct => true }), key.to_s.singularize)
141
+ end
142
+ else
143
+ if value.respond_to?(:to_xml)
144
+ value.to_xml(options.merge({ :root => key, :skip_instruct => true }))
145
+ else
146
+ type_name = XML_TYPE_NAMES[value.class.name]
147
+
148
+ key = dasherize ? key.to_s.dasherize : key.to_s
149
+
150
+ attributes = options[:skip_types] || value.nil? || type_name.nil? ? { } : { :type => type_name }
151
+ if value.nil?
152
+ attributes[:nil] = true
153
+ end
154
+
155
+ options[:builder].tag!(key,
156
+ XML_FORMATTING[type_name] ? XML_FORMATTING[type_name].call(value) : value,
157
+ attributes
158
+ )
159
+ end
160
+ end
161
+ end
162
+
163
+ yield options[:builder] if block_given?
164
+ end
165
+
166
+ end
167
+
168
+ module ClassMethods
169
+ def from_xml(xml)
170
+ # TODO: Refactor this into something much cleaner that doesn't rely on XmlSimple
171
+ typecast_xml_value(undasherize_keys(XmlSimple.xml_in_string(xml,
172
+ 'forcearray' => false,
173
+ 'forcecontent' => true,
174
+ 'keeproot' => true,
175
+ 'contentkey' => '__content__')
176
+ ))
177
+ end
178
+
179
+ private
180
+ def typecast_xml_value(value)
181
+ case value.class.to_s
182
+ when 'Hash'
183
+ if value['type'] == 'array'
184
+ child_key, entries = value.detect { |k,v| k != 'type' } # child_key is throwaway
185
+ if entries.nil? || (c = value['__content__'] && c.blank?)
186
+ []
187
+ else
188
+ case entries.class.to_s # something weird with classes not matching here. maybe singleton methods breaking is_a?
189
+ when "Array"
190
+ entries.collect { |v| typecast_xml_value(v) }
191
+ when "Hash"
192
+ [typecast_xml_value(entries)]
193
+ else
194
+ raise "can't typecast #{entries.inspect}"
195
+ end
196
+ end
197
+ elsif value.has_key?("__content__")
198
+ content = value["__content__"]
199
+ if parser = XML_PARSING[value["type"]]
200
+ if parser.arity == 2
201
+ XML_PARSING[value["type"]].call(content, value)
202
+ else
203
+ XML_PARSING[value["type"]].call(content)
204
+ end
205
+ else
206
+ content
207
+ end
208
+ elsif value['type'] == 'string' && value['nil'] != 'true'
209
+ ""
210
+ # blank or nil parsed values are represented by nil
211
+ elsif value.blank? || value['nil'] == 'true'
212
+ nil
213
+ # If the type is the only element which makes it then
214
+ # this still makes the value nil, except if type is
215
+ # a XML node(where type['value'] is a Hash)
216
+ elsif value['type'] && value.size == 1 && !value['type'].is_a?(::Hash)
217
+ nil
218
+ else
219
+ xml_value = value.inject({}) do |h,(k,v)|
220
+ h[k] = typecast_xml_value(v)
221
+ h
222
+ end
223
+
224
+ # Turn { :files => { :file => #<StringIO> } into { :files => #<StringIO> } so it is compatible with
225
+ # how multipart uploaded files from HTML appear
226
+ xml_value["file"].is_a?(StringIO) ? xml_value["file"] : xml_value
227
+ end
228
+ when 'Array'
229
+ value.map! { |i| typecast_xml_value(i) }
230
+ case value.length
231
+ when 0 then nil
232
+ when 1 then value.first
233
+ else value
234
+ end
235
+ when 'String'
236
+ value
237
+ else
238
+ raise "can't typecast #{value.class.name} - #{value.inspect}"
239
+ end
240
+ end
241
+
242
+ def undasherize_keys(params)
243
+ case params.class.to_s
244
+ when "Hash"
245
+ params.inject({}) do |h,(k,v)|
246
+ h[k.to_s.tr("-", "_")] = undasherize_keys(v)
247
+ h
248
+ end
249
+ when "Array"
250
+ params.map { |v| undasherize_keys(v) }
251
+ else
252
+ params
253
+ end
254
+ end
255
+ end
256
+ end
257
+ end
258
+ end
259
+ end
@@ -0,0 +1,23 @@
1
+ module ActiveSupport #:nodoc:
2
+ module CoreExtensions #:nodoc:
3
+ module Hash #:nodoc:
4
+ # Allows for deep merging
5
+ module DeepMerge
6
+ # Returns a new hash with +self+ and +other_hash+ merged recursively.
7
+ def deep_merge(other_hash)
8
+ self.merge(other_hash) do |key, oldval, newval|
9
+ oldval = oldval.to_hash if oldval.respond_to?(:to_hash)
10
+ newval = newval.to_hash if newval.respond_to?(:to_hash)
11
+ oldval.class.to_s == 'Hash' && newval.class.to_s == 'Hash' ? oldval.deep_merge(newval) : newval
12
+ end
13
+ end
14
+
15
+ # Returns a new hash with +self+ and +other_hash+ merged recursively.
16
+ # Modifies the receiver in place.
17
+ def deep_merge!(other_hash)
18
+ replace(deep_merge(other_hash))
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,19 @@
1
+ module ActiveSupport #:nodoc:
2
+ module CoreExtensions #:nodoc:
3
+ module Hash #:nodoc:
4
+ module Diff
5
+ # Returns a hash that represents the difference between two hashes.
6
+ #
7
+ # Examples:
8
+ #
9
+ # {1 => 2}.diff(1 => 2) # => {}
10
+ # {1 => 2}.diff(1 => 3) # => {1 => 2}
11
+ # {}.diff(1 => 2) # => {1 => 2}
12
+ # {1 => 2, 3 => 4}.diff(1 => 2) # => {3 => 4}
13
+ def diff(h2)
14
+ self.dup.delete_if { |k, v| h2[k] == v }.merge(h2.dup.delete_if { |k, v| self.has_key?(k) })
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,25 @@
1
+ require 'set'
2
+
3
+ module ActiveSupport #:nodoc:
4
+ module CoreExtensions #:nodoc:
5
+ module Hash #:nodoc:
6
+ # Return a hash that includes everything but the given keys. This is useful for
7
+ # limiting a set of parameters to everything but a few known toggles:
8
+ #
9
+ # @person.update_attributes(params[:person].except(:admin))
10
+ module Except
11
+ # Returns a new hash without the given keys.
12
+ def except(*keys)
13
+ dup.except!(*keys)
14
+ end
15
+
16
+ # Replaces the hash without the given keys.
17
+ def except!(*keys)
18
+ keys.map! { |key| convert_key(key) } if respond_to?(:convert_key)
19
+ keys.each { |key| delete(key) }
20
+ self
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,137 @@
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