hashie 3.5.7 → 5.0.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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +281 -195
- data/CONTRIBUTING.md +13 -6
- data/LICENSE +1 -1
- data/README.md +320 -60
- data/Rakefile +2 -2
- data/UPGRADING.md +121 -7
- data/hashie.gemspec +13 -7
- data/lib/hashie/clash.rb +12 -1
- data/lib/hashie/dash.rb +56 -35
- data/lib/hashie/extensions/active_support/core_ext/hash.rb +14 -0
- data/lib/hashie/extensions/coercion.rb +26 -19
- data/lib/hashie/extensions/dash/indifferent_access.rb +29 -1
- data/lib/hashie/extensions/dash/predefined_values.rb +88 -0
- data/lib/hashie/extensions/dash/property_translation.rb +59 -28
- data/lib/hashie/extensions/deep_fetch.rb +5 -3
- data/lib/hashie/extensions/deep_find.rb +14 -5
- data/lib/hashie/extensions/deep_locate.rb +22 -8
- data/lib/hashie/extensions/deep_merge.rb +26 -10
- data/lib/hashie/extensions/ignore_undeclared.rb +4 -5
- data/lib/hashie/extensions/indifferent_access.rb +43 -10
- data/lib/hashie/extensions/key_conflict_warning.rb +55 -0
- data/lib/hashie/extensions/mash/define_accessors.rb +90 -0
- data/lib/hashie/extensions/mash/keep_original_keys.rb +4 -5
- data/lib/hashie/extensions/mash/permissive_respond_to.rb +61 -0
- data/lib/hashie/extensions/mash/safe_assignment.rb +3 -1
- data/lib/hashie/extensions/mash/symbolize_keys.rb +6 -6
- data/lib/hashie/extensions/method_access.rb +47 -14
- data/lib/hashie/extensions/parsers/yaml_erb_parser.rb +28 -4
- data/lib/hashie/extensions/ruby_version_check.rb +5 -1
- data/lib/hashie/extensions/strict_key_access.rb +16 -13
- data/lib/hashie/extensions/stringify_keys.rb +1 -1
- data/lib/hashie/extensions/symbolize_keys.rb +13 -2
- data/lib/hashie/hash.rb +18 -11
- data/lib/hashie/mash.rb +147 -81
- data/lib/hashie/railtie.rb +7 -0
- data/lib/hashie/rash.rb +6 -6
- data/lib/hashie/utils.rb +28 -0
- data/lib/hashie/version.rb +1 -1
- data/lib/hashie.rb +22 -19
- metadata +23 -131
- data/spec/hashie/array_spec.rb +0 -29
- data/spec/hashie/clash_spec.rb +0 -70
- data/spec/hashie/dash_spec.rb +0 -573
- data/spec/hashie/extensions/autoload_spec.rb +0 -24
- data/spec/hashie/extensions/coercion_spec.rb +0 -631
- data/spec/hashie/extensions/dash/coercion_spec.rb +0 -13
- data/spec/hashie/extensions/dash/indifferent_access_spec.rb +0 -84
- data/spec/hashie/extensions/deep_fetch_spec.rb +0 -97
- data/spec/hashie/extensions/deep_find_spec.rb +0 -138
- data/spec/hashie/extensions/deep_locate_spec.rb +0 -137
- data/spec/hashie/extensions/deep_merge_spec.rb +0 -70
- data/spec/hashie/extensions/ignore_undeclared_spec.rb +0 -47
- data/spec/hashie/extensions/indifferent_access_spec.rb +0 -282
- data/spec/hashie/extensions/indifferent_access_with_rails_hwia_spec.rb +0 -208
- data/spec/hashie/extensions/key_conversion_spec.rb +0 -12
- data/spec/hashie/extensions/mash/keep_original_keys_spec.rb +0 -46
- data/spec/hashie/extensions/mash/safe_assignment_spec.rb +0 -50
- data/spec/hashie/extensions/mash/symbolize_keys_spec.rb +0 -39
- data/spec/hashie/extensions/merge_initializer_spec.rb +0 -23
- data/spec/hashie/extensions/method_access_spec.rb +0 -188
- data/spec/hashie/extensions/strict_key_access_spec.rb +0 -110
- data/spec/hashie/extensions/stringify_keys_spec.rb +0 -124
- data/spec/hashie/extensions/symbolize_keys_spec.rb +0 -129
- data/spec/hashie/hash_spec.rb +0 -84
- data/spec/hashie/mash_spec.rb +0 -763
- data/spec/hashie/parsers/yaml_erb_parser_spec.rb +0 -46
- data/spec/hashie/rash_spec.rb +0 -83
- data/spec/hashie/trash_spec.rb +0 -268
- data/spec/hashie/utils_spec.rb +0 -25
- data/spec/hashie/version_spec.rb +0 -7
- data/spec/hashie_spec.rb +0 -13
- data/spec/integration/omniauth/app.rb +0 -11
- data/spec/integration/omniauth/integration_spec.rb +0 -38
- data/spec/integration/omniauth-oauth2/app.rb +0 -53
- data/spec/integration/omniauth-oauth2/integration_spec.rb +0 -26
- data/spec/integration/omniauth-oauth2/some_site.rb +0 -38
- data/spec/integration/rails/app.rb +0 -48
- data/spec/integration/rails/integration_spec.rb +0 -26
- data/spec/integration/rails-without-dependency/integration_spec.rb +0 -15
- data/spec/spec_helper.rb +0 -23
- data/spec/support/integration_specs.rb +0 -36
- data/spec/support/logger.rb +0 -24
- data/spec/support/module_context.rb +0 -11
- data/spec/support/ruby_version_check.rb +0 -6
@@ -0,0 +1,61 @@
|
|
1
|
+
module Hashie
|
2
|
+
module Extensions
|
3
|
+
module Mash
|
4
|
+
# Allow a Mash to properly respond to everything
|
5
|
+
#
|
6
|
+
# By default, Mashes only say they respond to methods for keys that exist
|
7
|
+
# in their key set or any of the affix methods (e.g. setter, underbang,
|
8
|
+
# etc.). This causes issues when you try to use them within a
|
9
|
+
# SimpleDelegator or bind to a method for a key that is unset.
|
10
|
+
#
|
11
|
+
# This extension allows a Mash to properly respond to `respond_to?` and
|
12
|
+
# `method` for keys that have not yet been set. This enables full
|
13
|
+
# compatibility with SimpleDelegator and thunk-oriented programming.
|
14
|
+
#
|
15
|
+
# There is a trade-off with this extension: it will run slower than a
|
16
|
+
# regular Mash; insertions and initializations with keys run approximately
|
17
|
+
# 20% slower and cost approximately 19KB of memory per class that you
|
18
|
+
# make permissive.
|
19
|
+
#
|
20
|
+
# @api public
|
21
|
+
# @example Make a new, permissively responding Mash subclass
|
22
|
+
# class PermissiveMash < Hashie::Mash
|
23
|
+
# include Hashie::Extensions::Mash::PermissiveRespondTo
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# mash = PermissiveMash.new(a: 1)
|
27
|
+
# mash.respond_to? :b #=> true
|
28
|
+
module PermissiveRespondTo
|
29
|
+
# The Ruby hook for behavior when including the module
|
30
|
+
#
|
31
|
+
# @api private
|
32
|
+
# @private
|
33
|
+
# @return void
|
34
|
+
def self.included(base)
|
35
|
+
base.instance_variable_set :@_method_cache, base.instance_methods
|
36
|
+
base.define_singleton_method(:method_cache) { @_method_cache }
|
37
|
+
end
|
38
|
+
|
39
|
+
# The Ruby hook for determining what messages a class might respond to
|
40
|
+
#
|
41
|
+
# @api private
|
42
|
+
# @private
|
43
|
+
def respond_to_missing?(_method_name, _include_private = false)
|
44
|
+
true
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
# Override the Mash logging behavior to account for permissiveness
|
50
|
+
#
|
51
|
+
# @api private
|
52
|
+
# @private
|
53
|
+
def log_collision?(method_key)
|
54
|
+
self.class.method_cache.include?(method_key) &&
|
55
|
+
!self.class.disable_warnings?(method_key) &&
|
56
|
+
!(regular_key?(method_key) || regular_key?(method_key.to_s))
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -3,7 +3,9 @@ module Hashie
|
|
3
3
|
module Mash
|
4
4
|
module SafeAssignment
|
5
5
|
def custom_writer(key, *args) #:nodoc:
|
6
|
-
|
6
|
+
if !key?(key) && respond_to?(key, true)
|
7
|
+
raise ArgumentError, "The property #{key} clashes with an existing method."
|
8
|
+
end
|
7
9
|
super
|
8
10
|
end
|
9
11
|
|
@@ -5,7 +5,7 @@ module Hashie
|
|
5
5
|
#
|
6
6
|
# @example
|
7
7
|
# class LazyResponse < Hashie::Mash
|
8
|
-
# include Hashie::Extensions::Mash::
|
8
|
+
# include Hashie::Extensions::Mash::SymbolizeKeys
|
9
9
|
# end
|
10
10
|
#
|
11
11
|
# response = LazyResponse.new("id" => 123, "name" => "Rey").to_h
|
@@ -19,18 +19,18 @@ module Hashie
|
|
19
19
|
# @return [void]
|
20
20
|
# @raise [ArgumentError] when the base class isn't a Mash
|
21
21
|
def self.included(base)
|
22
|
-
|
22
|
+
raise ArgumentError, "#{base} must descent from Hashie::Mash" unless base <= Hashie::Mash
|
23
23
|
end
|
24
24
|
|
25
25
|
private
|
26
26
|
|
27
|
-
# Converts a key to a symbol
|
27
|
+
# Converts a key to a symbol, if possible
|
28
28
|
#
|
29
29
|
# @api private
|
30
|
-
# @param [
|
31
|
-
# @return [
|
30
|
+
# @param [<K>] key the key to attempt convert to a symbol
|
31
|
+
# @return [Symbol, K]
|
32
32
|
def convert_key(key)
|
33
|
-
key.to_sym
|
33
|
+
key.respond_to?(:to_sym) ? key.to_sym : key
|
34
34
|
end
|
35
35
|
end
|
36
36
|
end
|
@@ -27,7 +27,7 @@ module Hashie
|
|
27
27
|
#
|
28
28
|
# user.not_declared # => NoMethodError
|
29
29
|
module MethodReader
|
30
|
-
def
|
30
|
+
def respond_to_missing?(name, include_private = false)
|
31
31
|
return true if key?(name.to_s) || key?(name.to_sym)
|
32
32
|
super
|
33
33
|
end
|
@@ -67,7 +67,7 @@ module Hashie
|
|
67
67
|
# h['awesome'] # => 'sauce'
|
68
68
|
#
|
69
69
|
module MethodWriter
|
70
|
-
def
|
70
|
+
def respond_to_missing?(name, include_private = false)
|
71
71
|
return true if name.to_s =~ /=$/
|
72
72
|
super
|
73
73
|
end
|
@@ -106,7 +106,7 @@ module Hashie
|
|
106
106
|
# h.def? # => false
|
107
107
|
# h.hji? # => NoMethodError
|
108
108
|
module MethodQuery
|
109
|
-
def
|
109
|
+
def respond_to_missing?(name, include_private = false)
|
110
110
|
if query_method?(name) && indifferent_key?(key_from_query_method(name))
|
111
111
|
true
|
112
112
|
else
|
@@ -156,6 +156,22 @@ module Hashie
|
|
156
156
|
end
|
157
157
|
end
|
158
158
|
|
159
|
+
# A module shared between MethodOverridingWriter and MethodOverridingInitializer
|
160
|
+
# to contained shared logic. This module aids in redefining existing hash methods.
|
161
|
+
module RedefineMethod
|
162
|
+
protected
|
163
|
+
|
164
|
+
def method?(name)
|
165
|
+
methods.map(&:to_s).include?(name)
|
166
|
+
end
|
167
|
+
|
168
|
+
def redefine_method(method_name)
|
169
|
+
eigenclass = class << self; self; end
|
170
|
+
eigenclass.__send__(:alias_method, "__#{method_name}", method_name)
|
171
|
+
eigenclass.__send__(:define_method, method_name, -> { self[method_name] })
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
159
175
|
# MethodOverridingWriter gives you #key_name= shortcuts for
|
160
176
|
# writing to your hash. It allows methods to be overridden by
|
161
177
|
# #key_name= shortcuts and aliases those methods with two
|
@@ -181,6 +197,8 @@ module Hashie
|
|
181
197
|
# h.__zip # => [[['awesome', 'sauce'], ['zip', 'a-dee-doo-dah']]]
|
182
198
|
#
|
183
199
|
module MethodOverridingWriter
|
200
|
+
include RedefineMethod
|
201
|
+
|
184
202
|
def convert_key(key)
|
185
203
|
key.to_s
|
186
204
|
end
|
@@ -205,16 +223,6 @@ module Hashie
|
|
205
223
|
def already_overridden?(name)
|
206
224
|
method?("__#{name}")
|
207
225
|
end
|
208
|
-
|
209
|
-
def method?(name)
|
210
|
-
methods.map(&:to_s).include?(name)
|
211
|
-
end
|
212
|
-
|
213
|
-
def redefine_method(method_name)
|
214
|
-
eigenclass = class << self; self; end
|
215
|
-
eigenclass.__send__(:alias_method, "__#{method_name}", method_name)
|
216
|
-
eigenclass.__send__(:define_method, method_name, -> { self[method_name] })
|
217
|
-
end
|
218
226
|
end
|
219
227
|
|
220
228
|
# A macro module that will automatically include MethodReader,
|
@@ -225,10 +233,35 @@ module Hashie
|
|
225
233
|
# underscores.
|
226
234
|
module MethodAccessWithOverride
|
227
235
|
def self.included(base)
|
228
|
-
[MethodReader, MethodOverridingWriter,
|
236
|
+
[MethodReader, MethodOverridingWriter,
|
237
|
+
MethodQuery, MethodOverridingInitializer].each do |mod|
|
229
238
|
base.send :include, mod
|
230
239
|
end
|
231
240
|
end
|
232
241
|
end
|
242
|
+
|
243
|
+
# MethodOverridingInitializer allows you to override default hash
|
244
|
+
# methods when passing in values from an existing hash. The overriden
|
245
|
+
# methods are aliased with two leading underscores.
|
246
|
+
#
|
247
|
+
# @example
|
248
|
+
# class MyHash < Hash
|
249
|
+
# include Hashie::Extensions::MethodOverridingInitializer
|
250
|
+
# end
|
251
|
+
#
|
252
|
+
# h = MyHash.new(zip: 'a-dee-doo-dah')
|
253
|
+
# h.zip # => 'a-dee-doo-dah'
|
254
|
+
# h.__zip # => [[['zip', 'a-dee-doo-dah']]]
|
255
|
+
module MethodOverridingInitializer
|
256
|
+
include RedefineMethod
|
257
|
+
|
258
|
+
def initialize(hash = {})
|
259
|
+
hash.each do |key, value|
|
260
|
+
skey = key.to_s
|
261
|
+
redefine_method(skey) if method?(skey)
|
262
|
+
self[skey] = value
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
233
266
|
end
|
234
267
|
end
|
@@ -1,22 +1,46 @@
|
|
1
1
|
require 'yaml'
|
2
2
|
require 'erb'
|
3
|
+
require 'pathname'
|
4
|
+
|
3
5
|
module Hashie
|
4
6
|
module Extensions
|
5
7
|
module Parsers
|
6
8
|
class YamlErbParser
|
7
|
-
def initialize(file_path)
|
9
|
+
def initialize(file_path, options = {})
|
8
10
|
@content = File.read(file_path)
|
9
11
|
@file_path = file_path.is_a?(Pathname) ? file_path.to_s : file_path
|
12
|
+
@options = options
|
10
13
|
end
|
11
14
|
|
12
15
|
def perform
|
13
16
|
template = ERB.new(@content)
|
14
17
|
template.filename = @file_path
|
15
|
-
|
18
|
+
permitted_classes = @options.fetch(:permitted_classes) { [] }
|
19
|
+
permitted_symbols = @options.fetch(:permitted_symbols) { [] }
|
20
|
+
aliases = @options.fetch(:aliases) { true }
|
21
|
+
|
22
|
+
yaml_safe_load(template, permitted_classes, permitted_symbols, aliases)
|
16
23
|
end
|
17
24
|
|
18
|
-
def self.perform(file_path)
|
19
|
-
new(file_path).perform
|
25
|
+
def self.perform(file_path, options = {})
|
26
|
+
new(file_path, options).perform
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
if Gem::Version.new(Psych::VERSION) >= Gem::Version.new('3.1.0') # Ruby 2.6+
|
32
|
+
def yaml_safe_load(template, permitted_classes, permitted_symbols, aliases)
|
33
|
+
YAML.safe_load(
|
34
|
+
template.result,
|
35
|
+
permitted_classes: permitted_classes,
|
36
|
+
permitted_symbols: permitted_symbols,
|
37
|
+
aliases: aliases
|
38
|
+
)
|
39
|
+
end
|
40
|
+
else
|
41
|
+
def yaml_safe_load(template, permitted_classes, permitted_symbols, aliases)
|
42
|
+
YAML.safe_load(template.result, permitted_classes, permitted_symbols, aliases)
|
43
|
+
end
|
20
44
|
end
|
21
45
|
end
|
22
46
|
end
|
@@ -9,7 +9,11 @@ module Hashie
|
|
9
9
|
|
10
10
|
module ClassMethods
|
11
11
|
def with_minimum_ruby(version)
|
12
|
-
yield if
|
12
|
+
yield if with_minimum_ruby?(version)
|
13
|
+
end
|
14
|
+
|
15
|
+
def with_minimum_ruby?(version)
|
16
|
+
RubyVersion.new(RUBY_VERSION) >= RubyVersion.new(version)
|
13
17
|
end
|
14
18
|
end
|
15
19
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module Hashie
|
2
2
|
module Extensions
|
3
|
-
# SRP: This extension will fail an error whenever a key is accessed
|
3
|
+
# SRP: This extension will fail an error whenever a key is accessed
|
4
|
+
# that does not exist in the hash.
|
4
5
|
#
|
5
6
|
# EXAMPLE:
|
6
7
|
#
|
@@ -15,12 +16,15 @@ module Hashie
|
|
15
16
|
# >> hash[:cow]
|
16
17
|
# KeyError: key not found: :cow
|
17
18
|
#
|
18
|
-
# NOTE: For googlers coming from Python to Ruby, this extension makes a Hash
|
19
|
+
# NOTE: For googlers coming from Python to Ruby, this extension makes a Hash
|
20
|
+
# behave more like a "Dictionary".
|
19
21
|
#
|
20
22
|
module StrictKeyAccess
|
21
23
|
class DefaultError < StandardError
|
22
|
-
def initialize
|
23
|
-
super
|
24
|
+
def initialize
|
25
|
+
super('Setting or using a default with Hashie::Extensions::StrictKeyAccess'\
|
26
|
+
' does not make sense'
|
27
|
+
)
|
24
28
|
end
|
25
29
|
end
|
26
30
|
|
@@ -46,27 +50,26 @@ module Hashie
|
|
46
50
|
end
|
47
51
|
|
48
52
|
def default(_ = nil)
|
49
|
-
|
53
|
+
raise DefaultError
|
50
54
|
end
|
51
55
|
|
52
56
|
def default=(_)
|
53
|
-
|
57
|
+
raise DefaultError
|
54
58
|
end
|
55
59
|
|
56
60
|
def default_proc
|
57
|
-
|
61
|
+
raise DefaultError
|
58
62
|
end
|
59
63
|
|
60
64
|
def default_proc=(_)
|
61
|
-
|
65
|
+
raise DefaultError
|
62
66
|
end
|
63
67
|
|
64
68
|
def key(value)
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
result
|
69
|
+
super.tap do |result|
|
70
|
+
if result.nil? && (!key?(result) || self[result] != value)
|
71
|
+
raise KeyError, "key not found with value of #{value.inspect}"
|
72
|
+
end
|
70
73
|
end
|
71
74
|
end
|
72
75
|
end
|
@@ -44,7 +44,7 @@ module Hashie
|
|
44
44
|
# test # => {'abc' => 'def'}
|
45
45
|
def stringify_keys!(hash)
|
46
46
|
hash.extend(Hashie::Extensions::StringifyKeys) unless hash.respond_to?(:stringify_keys!)
|
47
|
-
hash.keys.each do |k|
|
47
|
+
hash.keys.each do |k| # rubocop:disable Performance/HashEachMethods
|
48
48
|
stringify_keys_recursively!(hash[k])
|
49
49
|
hash[k.to_s] = hash.delete(k)
|
50
50
|
end
|
@@ -44,9 +44,9 @@ module Hashie
|
|
44
44
|
# test # => {:abc => 'def'}
|
45
45
|
def symbolize_keys!(hash)
|
46
46
|
hash.extend(Hashie::Extensions::SymbolizeKeys) unless hash.respond_to?(:symbolize_keys!)
|
47
|
-
hash.keys.each do |k|
|
47
|
+
hash.keys.each do |k| # rubocop:disable Performance/HashEachMethods
|
48
48
|
symbolize_keys_recursively!(hash[k])
|
49
|
-
hash[k
|
49
|
+
hash[convert_key(k)] = hash.delete(k)
|
50
50
|
end
|
51
51
|
hash
|
52
52
|
end
|
@@ -61,6 +61,17 @@ module Hashie
|
|
61
61
|
symbolize_keys!(new_hash)
|
62
62
|
end
|
63
63
|
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
# Converts a key to a symbol, if possible
|
68
|
+
#
|
69
|
+
# @api private
|
70
|
+
# @param [<K>] key the key to attempt convert to a symbol
|
71
|
+
# @return [Symbol, K]
|
72
|
+
def convert_key(key)
|
73
|
+
key.respond_to?(:to_sym) ? key.to_sym : key
|
74
|
+
end
|
64
75
|
end
|
65
76
|
|
66
77
|
class << self
|
data/lib/hashie/hash.rb
CHANGED
@@ -17,21 +17,22 @@ module Hashie
|
|
17
17
|
# Converts a mash back to a hash (with stringified or symbolized keys)
|
18
18
|
def to_hash(options = {})
|
19
19
|
out = {}
|
20
|
-
|
21
|
-
assignment_key =
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
20
|
+
each_key do |k|
|
21
|
+
assignment_key =
|
22
|
+
if options[:stringify_keys]
|
23
|
+
k.to_s
|
24
|
+
elsif options[:symbolize_keys] && k.respond_to?(:to_sym)
|
25
|
+
k.to_sym
|
26
|
+
else
|
27
|
+
k
|
28
|
+
end
|
28
29
|
if self[k].is_a?(Array)
|
29
30
|
out[assignment_key] ||= []
|
30
31
|
self[k].each do |array_object|
|
31
|
-
out[assignment_key] << (
|
32
|
+
out[assignment_key] << maybe_convert_to_hash(array_object, options)
|
32
33
|
end
|
33
34
|
else
|
34
|
-
out[assignment_key] = (
|
35
|
+
out[assignment_key] = maybe_convert_to_hash(self[k], options)
|
35
36
|
end
|
36
37
|
end
|
37
38
|
out
|
@@ -44,8 +45,14 @@ module Hashie
|
|
44
45
|
|
45
46
|
private
|
46
47
|
|
48
|
+
def maybe_convert_to_hash(object, options)
|
49
|
+
return object unless object.is_a?(Hash) || object.respond_to?(:to_hash)
|
50
|
+
|
51
|
+
flexibly_convert_to_hash(object, options)
|
52
|
+
end
|
53
|
+
|
47
54
|
def flexibly_convert_to_hash(object, options = {})
|
48
|
-
if object.method(:to_hash).arity
|
55
|
+
if object.method(:to_hash).arity.zero?
|
49
56
|
object.to_hash
|
50
57
|
else
|
51
58
|
object.to_hash(options)
|