hashie 3.4.2 → 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 +518 -122
- data/CONTRIBUTING.md +24 -7
- data/LICENSE +1 -1
- data/README.md +455 -48
- data/Rakefile +18 -1
- data/UPGRADING.md +157 -7
- data/hashie.gemspec +14 -7
- data/lib/hashie/array.rb +21 -0
- data/lib/hashie/clash.rb +24 -12
- data/lib/hashie/dash.rb +56 -31
- data/lib/hashie/extensions/active_support/core_ext/hash.rb +14 -0
- data/lib/hashie/extensions/array/pretty_inspect.rb +19 -0
- data/lib/hashie/extensions/coercion.rb +91 -52
- data/lib/hashie/extensions/dash/coercion.rb +25 -0
- data/lib/hashie/extensions/dash/indifferent_access.rb +30 -1
- data/lib/hashie/extensions/dash/predefined_values.rb +88 -0
- data/lib/hashie/extensions/dash/property_translation.rb +59 -30
- 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 +40 -21
- data/lib/hashie/extensions/deep_merge.rb +28 -10
- data/lib/hashie/extensions/ignore_undeclared.rb +6 -4
- data/lib/hashie/extensions/indifferent_access.rb +49 -8
- 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 +53 -0
- 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 +38 -0
- data/lib/hashie/extensions/method_access.rb +77 -19
- data/lib/hashie/extensions/parsers/yaml_erb_parser.rb +29 -5
- data/lib/hashie/extensions/ruby_version.rb +60 -0
- data/lib/hashie/extensions/ruby_version_check.rb +21 -0
- data/lib/hashie/extensions/strict_key_access.rb +77 -0
- data/lib/hashie/extensions/stringify_keys.rb +8 -5
- data/lib/hashie/extensions/symbolize_keys.rb +21 -7
- data/lib/hashie/hash.rb +18 -11
- data/lib/hashie/logger.rb +18 -0
- data/lib/hashie/mash.rb +196 -55
- data/lib/hashie/railtie.rb +21 -0
- data/lib/hashie/rash.rb +7 -7
- data/lib/hashie/utils.rb +44 -0
- data/lib/hashie/version.rb +1 -1
- data/lib/hashie.rb +34 -16
- metadata +30 -79
- data/spec/hashie/clash_spec.rb +0 -48
- data/spec/hashie/dash_spec.rb +0 -513
- data/spec/hashie/extensions/autoload_spec.rb +0 -24
- data/spec/hashie/extensions/coercion_spec.rb +0 -625
- 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 -45
- data/spec/hashie/extensions/deep_locate_spec.rb +0 -124
- data/spec/hashie/extensions/deep_merge_spec.rb +0 -45
- data/spec/hashie/extensions/ignore_undeclared_spec.rb +0 -46
- data/spec/hashie/extensions/indifferent_access_spec.rb +0 -219
- 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/safe_assignment_spec.rb +0 -23
- data/spec/hashie/extensions/merge_initializer_spec.rb +0 -23
- data/spec/hashie/extensions/method_access_spec.rb +0 -184
- data/spec/hashie/extensions/stringify_keys_spec.rb +0 -101
- data/spec/hashie/extensions/symbolize_keys_spec.rb +0 -106
- data/spec/hashie/hash_spec.rb +0 -84
- data/spec/hashie/mash_spec.rb +0 -683
- data/spec/hashie/parsers/yaml_erb_parser_spec.rb +0 -29
- data/spec/hashie/rash_spec.rb +0 -77
- data/spec/hashie/trash_spec.rb +0 -268
- data/spec/hashie/version_spec.rb +0 -7
- data/spec/spec_helper.rb +0 -15
- data/spec/support/module_context.rb +0 -11
- data/spec/support/ruby_version.rb +0 -10
data/lib/hashie/mash.rb
CHANGED
@@ -1,4 +1,8 @@
|
|
1
1
|
require 'hashie/hash'
|
2
|
+
require 'hashie/array'
|
3
|
+
require 'hashie/utils'
|
4
|
+
require 'hashie/logger'
|
5
|
+
require 'hashie/extensions/key_conflict_warning'
|
2
6
|
|
3
7
|
module Hashie
|
4
8
|
# Mash allows you to create pseudo-objects that have method-like
|
@@ -12,9 +16,12 @@ module Hashie
|
|
12
16
|
#
|
13
17
|
# * No punctuation: Returns the value of the hash for that key, or nil if none exists.
|
14
18
|
# * Assignment (<tt>=</tt>): Sets the attribute of the given method name.
|
15
|
-
# *
|
16
|
-
#
|
17
|
-
# *
|
19
|
+
# * Truthiness (<tt>?</tt>): Returns true or false depending on the truthiness of
|
20
|
+
# the attribute, or false if the key is not set.
|
21
|
+
# * Bang (<tt>!</tt>): Forces the existence of this key, used for deep Mashes. Think of it
|
22
|
+
# as "touch" for mashes.
|
23
|
+
# * Under Bang (<tt>_</tt>): Like Bang, but returns a new Mash rather than creating a key.
|
24
|
+
# Used to test existance in deep Mashes.
|
18
25
|
#
|
19
26
|
# == Basic Example
|
20
27
|
#
|
@@ -55,19 +62,20 @@ module Hashie
|
|
55
62
|
# mash.author # => <Mash>
|
56
63
|
#
|
57
64
|
class Mash < Hash
|
58
|
-
include Hashie::Extensions::
|
65
|
+
include Hashie::Extensions::RubyVersionCheck
|
66
|
+
extend Hashie::Extensions::KeyConflictWarning
|
59
67
|
|
60
|
-
ALLOWED_SUFFIXES = %w
|
61
|
-
SUFFIXES_PARSER = /(.*?)([#{ALLOWED_SUFFIXES.join}]?)$/
|
68
|
+
ALLOWED_SUFFIXES = %w[? ! = _].freeze
|
62
69
|
|
63
70
|
def self.load(path, options = {})
|
64
71
|
@_mashes ||= new
|
65
72
|
|
66
73
|
return @_mashes[path] if @_mashes.key?(path)
|
67
|
-
|
74
|
+
raise ArgumentError, "The following file doesn't exist: #{path}" unless File.file?(path)
|
68
75
|
|
69
|
-
|
70
|
-
|
76
|
+
options = options.dup
|
77
|
+
parser = options.delete(:parser) { Hashie::Extensions::Parsers::YamlErbParser }
|
78
|
+
@_mashes[path] = new(parser.perform(path, options)).freeze
|
71
79
|
end
|
72
80
|
|
73
81
|
def to_module(mash_method_name = :settings)
|
@@ -79,7 +87,11 @@ module Hashie
|
|
79
87
|
end
|
80
88
|
end
|
81
89
|
|
82
|
-
|
90
|
+
def with_accessors!
|
91
|
+
extend Hashie::Extensions::Mash::DefineAccessors
|
92
|
+
end
|
93
|
+
|
94
|
+
alias to_s inspect
|
83
95
|
|
84
96
|
# If you pass in an existing hash, it will
|
85
97
|
# convert it to a Mash including recursively
|
@@ -90,13 +102,26 @@ module Hashie
|
|
90
102
|
default ? super(default) : super(&blk)
|
91
103
|
end
|
92
104
|
|
93
|
-
|
105
|
+
# Creates a new anonymous subclass with key conflict
|
106
|
+
# warnings disabled. You may pass an array of method
|
107
|
+
# symbols to restrict the disabled warnings to.
|
108
|
+
# Hashie::Mash.quiet.new(hash) all warnings disabled.
|
109
|
+
# Hashie::Mash.quiet(:zip).new(hash) only zip warning
|
110
|
+
# is disabled.
|
111
|
+
def self.quiet(*method_keys)
|
112
|
+
@memoized_classes ||= {}
|
113
|
+
@memoized_classes[method_keys] ||= Class.new(self) do
|
114
|
+
disable_warnings(*method_keys)
|
115
|
+
end
|
116
|
+
end
|
94
117
|
|
95
|
-
|
96
|
-
alias_method :regular_writer, :[]=
|
118
|
+
class << self; alias [] new; end
|
97
119
|
|
98
|
-
|
99
|
-
|
120
|
+
alias regular_reader []
|
121
|
+
alias regular_writer []=
|
122
|
+
|
123
|
+
# Retrieves an attribute set in the Mash. Will convert a key passed in
|
124
|
+
# as a symbol to a string before retrieving.
|
100
125
|
def custom_reader(key)
|
101
126
|
default_proc.call(self, key) if default_proc && !key?(key)
|
102
127
|
value = regular_reader(convert_key(key))
|
@@ -104,15 +129,16 @@ module Hashie
|
|
104
129
|
value
|
105
130
|
end
|
106
131
|
|
107
|
-
# Sets an attribute in the Mash.
|
108
|
-
#
|
109
|
-
#
|
132
|
+
# Sets an attribute in the Mash. Symbol keys will be converted to
|
133
|
+
# strings before being set, and Hashes will be converted into Mashes
|
134
|
+
# for nesting purposes.
|
110
135
|
def custom_writer(key, value, convert = true) #:nodoc:
|
136
|
+
log_built_in_message(key) if key.respond_to?(:to_sym) && log_collision?(key.to_sym)
|
111
137
|
regular_writer(convert_key(key), convert ? convert_value(value) : value)
|
112
138
|
end
|
113
139
|
|
114
|
-
|
115
|
-
|
140
|
+
alias [] custom_reader
|
141
|
+
alias []= custom_writer
|
116
142
|
|
117
143
|
# This is the bang method reader, it will return a new Mash
|
118
144
|
# if there isn't a value already assigned to the key requested.
|
@@ -145,44 +171,89 @@ module Hashie
|
|
145
171
|
super(*keys.map { |key| convert_key(key) })
|
146
172
|
end
|
147
173
|
|
148
|
-
|
174
|
+
# Returns a new instance of the class it was called on, using its keys as
|
175
|
+
# values, and its values as keys. The new values and keys will always be
|
176
|
+
# strings.
|
177
|
+
def invert
|
178
|
+
self.class.new(super)
|
179
|
+
end
|
180
|
+
|
181
|
+
# Returns a new instance of the class it was called on, containing elements
|
182
|
+
# for which the given block returns false.
|
183
|
+
def reject(&blk)
|
184
|
+
self.class.new(super(&blk))
|
185
|
+
end
|
186
|
+
|
187
|
+
# Returns a new instance of the class it was called on, containing elements
|
188
|
+
# for which the given block returns true.
|
189
|
+
def select(&blk)
|
190
|
+
self.class.new(super(&blk))
|
191
|
+
end
|
192
|
+
|
193
|
+
alias regular_dup dup
|
149
194
|
# Duplicates the current mash as a new mash.
|
150
195
|
def dup
|
151
|
-
self.class.new(self, default)
|
196
|
+
self.class.new(self, default, &default_proc)
|
152
197
|
end
|
153
198
|
|
199
|
+
alias regular_key? key?
|
154
200
|
def key?(key)
|
155
201
|
super(convert_key(key))
|
156
202
|
end
|
157
|
-
|
158
|
-
|
159
|
-
|
203
|
+
alias has_key? key?
|
204
|
+
alias include? key?
|
205
|
+
alias member? key?
|
206
|
+
|
207
|
+
if with_minimum_ruby?('2.6.0')
|
208
|
+
# Performs a deep_update on a duplicate of the
|
209
|
+
# current mash.
|
210
|
+
def deep_merge(*other_hashes, &blk)
|
211
|
+
dup.deep_update(*other_hashes, &blk)
|
212
|
+
end
|
213
|
+
|
214
|
+
# Recursively merges this mash with the passed
|
215
|
+
# in hash, merging each hash in the hierarchy.
|
216
|
+
def deep_update(*other_hashes, &blk)
|
217
|
+
other_hashes.each do |other_hash|
|
218
|
+
_deep_update(other_hash, &blk)
|
219
|
+
end
|
220
|
+
self
|
221
|
+
end
|
222
|
+
else
|
223
|
+
# Performs a deep_update on a duplicate of the
|
224
|
+
# current mash.
|
225
|
+
def deep_merge(other_hash, &blk)
|
226
|
+
dup.deep_update(other_hash, &blk)
|
227
|
+
end
|
160
228
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
229
|
+
# Recursively merges this mash with the passed
|
230
|
+
# in hash, merging each hash in the hierarchy.
|
231
|
+
def deep_update(other_hash, &blk)
|
232
|
+
_deep_update(other_hash, &blk)
|
233
|
+
self
|
234
|
+
end
|
165
235
|
end
|
166
|
-
alias_method :merge, :deep_merge
|
167
236
|
|
168
|
-
#
|
169
|
-
#
|
170
|
-
|
237
|
+
# Alias these lexically so they get the correctly defined
|
238
|
+
# #deep_merge and #deep_update based on ruby version.
|
239
|
+
alias merge deep_merge
|
240
|
+
alias deep_merge! deep_update
|
241
|
+
alias update deep_update
|
242
|
+
alias merge! update
|
243
|
+
|
244
|
+
def _deep_update(other_hash, &blk)
|
171
245
|
other_hash.each_pair do |k, v|
|
172
246
|
key = convert_key(k)
|
173
|
-
if
|
247
|
+
if v.is_a?(::Hash) && key?(key) && regular_reader(key).is_a?(Mash)
|
174
248
|
custom_reader(key).deep_update(v, &blk)
|
175
249
|
else
|
176
250
|
value = convert_value(v, true)
|
177
|
-
value = convert_value(
|
251
|
+
value = convert_value(yield(key, self[k], value), true) if blk && key?(k)
|
178
252
|
custom_writer(key, value, false)
|
179
253
|
end
|
180
254
|
end
|
181
|
-
self
|
182
255
|
end
|
183
|
-
|
184
|
-
alias_method :update, :deep_update
|
185
|
-
alias_method :merge!, :update
|
256
|
+
private :_deep_update
|
186
257
|
|
187
258
|
# Assigns a value to a key
|
188
259
|
def assign_property(name, value)
|
@@ -211,10 +282,9 @@ module Hashie
|
|
211
282
|
|
212
283
|
def respond_to_missing?(method_name, *args)
|
213
284
|
return true if key?(method_name)
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
return true
|
285
|
+
suffix = method_suffix(method_name)
|
286
|
+
if suffix
|
287
|
+
true
|
218
288
|
else
|
219
289
|
super
|
220
290
|
end
|
@@ -225,17 +295,17 @@ module Hashie
|
|
225
295
|
method_name.end_with?(*ALLOWED_SUFFIXES) && key?(method_name.chop)
|
226
296
|
end
|
227
297
|
|
228
|
-
def method_missing(method_name, *args, &blk)
|
298
|
+
def method_missing(method_name, *args, &blk) # rubocop:disable Style/MethodMissing
|
229
299
|
return self.[](method_name, &blk) if key?(method_name)
|
230
|
-
name, suffix =
|
300
|
+
name, suffix = method_name_and_suffix(method_name)
|
231
301
|
case suffix
|
232
|
-
when '='
|
302
|
+
when '='.freeze
|
233
303
|
assign_property(name, args.first)
|
234
|
-
when '?'
|
304
|
+
when '?'.freeze
|
235
305
|
!!self[name]
|
236
|
-
when '!'
|
306
|
+
when '!'.freeze
|
237
307
|
initializing_reader(name)
|
238
|
-
when '_'
|
308
|
+
when '_'.freeze
|
239
309
|
underbang_reader(name)
|
240
310
|
else
|
241
311
|
self[method_name]
|
@@ -249,18 +319,63 @@ module Hashie
|
|
249
319
|
|
250
320
|
# another ActiveSupport method, see issue #270
|
251
321
|
def reverse_merge(other_hash)
|
252
|
-
|
322
|
+
self.class.new(other_hash).merge(self)
|
323
|
+
end
|
324
|
+
|
325
|
+
with_minimum_ruby('2.3.0') do
|
326
|
+
def dig(*keys)
|
327
|
+
super(*keys.map { |key| convert_key(key) })
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
with_minimum_ruby('2.4.0') do
|
332
|
+
def transform_values(&blk)
|
333
|
+
self.class.new(super(&blk))
|
334
|
+
end
|
335
|
+
|
336
|
+
# Returns a new instance of the class it was called on, with nil values
|
337
|
+
# removed.
|
338
|
+
def compact
|
339
|
+
self.class.new(super)
|
340
|
+
end
|
341
|
+
end
|
342
|
+
|
343
|
+
with_minimum_ruby('2.5.0') do
|
344
|
+
def slice(*keys)
|
345
|
+
string_keys = keys.map { |key| convert_key(key) }
|
346
|
+
self.class.new(super(*string_keys))
|
347
|
+
end
|
348
|
+
|
349
|
+
def transform_keys(&blk)
|
350
|
+
self.class.new(super(&blk))
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
354
|
+
with_minimum_ruby('3.0.0') do
|
355
|
+
def except(*keys)
|
356
|
+
string_keys = keys.map { |key| convert_key(key) }
|
357
|
+
self.class.new(super(*string_keys))
|
358
|
+
end
|
253
359
|
end
|
254
360
|
|
255
361
|
protected
|
256
362
|
|
363
|
+
def method_name_and_suffix(method_name)
|
364
|
+
method_name = method_name.to_s
|
365
|
+
if method_name.end_with?(*ALLOWED_SUFFIXES)
|
366
|
+
[method_name[0..-2], method_name[-1]]
|
367
|
+
else
|
368
|
+
[method_name[0..-1], nil]
|
369
|
+
end
|
370
|
+
end
|
371
|
+
|
257
372
|
def method_suffix(method_name)
|
258
|
-
|
259
|
-
[
|
373
|
+
method_name = method_name.to_s
|
374
|
+
method_name[-1] if method_name.end_with?(*ALLOWED_SUFFIXES)
|
260
375
|
end
|
261
376
|
|
262
377
|
def convert_key(key) #:nodoc:
|
263
|
-
key.to_s
|
378
|
+
key.respond_to?(:to_sym) ? key.to_s : key
|
264
379
|
end
|
265
380
|
|
266
381
|
def convert_value(val, duping = false) #:nodoc:
|
@@ -272,11 +387,37 @@ module Hashie
|
|
272
387
|
when ::Hash
|
273
388
|
val = val.dup if duping
|
274
389
|
self.class.new(val)
|
275
|
-
when Array
|
276
|
-
val.map { |e| convert_value(e) }
|
390
|
+
when ::Array
|
391
|
+
Array.new(val.map { |e| convert_value(e) })
|
277
392
|
else
|
278
393
|
val
|
279
394
|
end
|
280
395
|
end
|
396
|
+
|
397
|
+
private
|
398
|
+
|
399
|
+
def log_built_in_message(method_key)
|
400
|
+
return if self.class.disable_warnings?(method_key)
|
401
|
+
|
402
|
+
method_information = Hashie::Utils.method_information(method(method_key))
|
403
|
+
|
404
|
+
Hashie.logger.warn(
|
405
|
+
'You are setting a key that conflicts with a built-in method ' \
|
406
|
+
"#{self.class}##{method_key} #{method_information}. " \
|
407
|
+
'This can cause unexpected behavior when accessing the key as a ' \
|
408
|
+
'property. You can still access the key via the #[] method.'
|
409
|
+
)
|
410
|
+
end
|
411
|
+
|
412
|
+
def log_collision?(method_key)
|
413
|
+
return unless method_key.is_a?(String) || method_key.is_a?(Symbol)
|
414
|
+
return unless respond_to?(method_key)
|
415
|
+
|
416
|
+
_, suffix = method_name_and_suffix(method_key)
|
417
|
+
|
418
|
+
(!suffix || suffix == '='.freeze) &&
|
419
|
+
!self.class.disable_warnings?(method_key) &&
|
420
|
+
!(regular_key?(method_key) || regular_key?(method_key.to_s))
|
421
|
+
end
|
281
422
|
end
|
282
423
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
begin
|
2
|
+
require 'rails/railtie'
|
3
|
+
|
4
|
+
module Hashie
|
5
|
+
class Railtie < Rails::Railtie
|
6
|
+
# Set the Hashie.logger to use Rails.logger when used with rails.
|
7
|
+
initializer 'hashie.configure_logger', after: 'initialize_logger' do
|
8
|
+
Hashie.logger = Rails.logger
|
9
|
+
end
|
10
|
+
|
11
|
+
initializer 'hashie.patch_hash_except', after: 'load_active_support' do
|
12
|
+
if Rails::VERSION::MAJOR >= 6
|
13
|
+
require 'hashie/extensions/active_support/core_ext/hash'
|
14
|
+
Hashie::Mash.send(:include, Hashie::Extensions::ActiveSupport::CoreExt::Hash)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
rescue LoadError => e
|
20
|
+
Hashie.logger.info("Hashie skipping railtie as #{e.message}")
|
21
|
+
end
|
data/lib/hashie/rash.rb
CHANGED
@@ -64,7 +64,7 @@ module Hashie
|
|
64
64
|
# Raise (or yield) unless something matches the key.
|
65
65
|
#
|
66
66
|
def fetch(*args)
|
67
|
-
|
67
|
+
raise ArgumentError, "Expected 1-2 arguments, got #{args.length}" \
|
68
68
|
unless (1..2).cover?(args.length)
|
69
69
|
|
70
70
|
key, default = args
|
@@ -78,7 +78,7 @@ module Hashie
|
|
78
78
|
elsif default
|
79
79
|
default
|
80
80
|
else
|
81
|
-
|
81
|
+
raise KeyError, "key not found: #{key.inspect}"
|
82
82
|
end
|
83
83
|
end
|
84
84
|
|
@@ -117,7 +117,7 @@ module Hashie
|
|
117
117
|
end
|
118
118
|
|
119
119
|
when Regexp
|
120
|
-
# Reverse operation: `rash[/regexp/]` returns all
|
120
|
+
# Reverse operation: `rash[/regexp/]` returns all string keys matching the regexp
|
121
121
|
@hash.each do |key, val|
|
122
122
|
yield val if key.is_a?(String) && query =~ key
|
123
123
|
end
|
@@ -125,18 +125,18 @@ module Hashie
|
|
125
125
|
end
|
126
126
|
|
127
127
|
def method_missing(*args, &block)
|
128
|
-
@hash.send(*args, &block)
|
128
|
+
@hash.send(*args, &block) || super
|
129
129
|
end
|
130
130
|
|
131
|
-
def respond_to_missing?(
|
132
|
-
@hash.respond_to?(
|
131
|
+
def respond_to_missing?(method_name, _include_private = false)
|
132
|
+
@hash.respond_to?(method_name)
|
133
133
|
end
|
134
134
|
|
135
135
|
private
|
136
136
|
|
137
137
|
def optimize_if_necessary!
|
138
138
|
return unless (@lookups += 1) >= @optimize_every
|
139
|
-
@regexes = @
|
139
|
+
@regexes = @regexes.sort_by { |regex| -@regex_counts[regex] }
|
140
140
|
@lookups = 0
|
141
141
|
end
|
142
142
|
end
|
data/lib/hashie/utils.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
module Hashie
|
2
|
+
# A collection of helper methods that can be used throughout the gem.
|
3
|
+
module Utils
|
4
|
+
# Describes a method by where it was defined.
|
5
|
+
#
|
6
|
+
# @param bound_method [Method] The method to describe.
|
7
|
+
# @return [String]
|
8
|
+
def self.method_information(bound_method)
|
9
|
+
if bound_method.source_location
|
10
|
+
"defined at #{bound_method.source_location.join(':')}"
|
11
|
+
else
|
12
|
+
"defined in #{bound_method.owner}"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# Duplicates a value or returns the value when it is not duplicable
|
17
|
+
#
|
18
|
+
# @api public
|
19
|
+
#
|
20
|
+
# @param value [Object] the value to safely duplicate
|
21
|
+
# @return [Object] the duplicated value
|
22
|
+
def self.safe_dup(value)
|
23
|
+
case value
|
24
|
+
when Complex, FalseClass, NilClass, Rational, Method, Symbol, TrueClass, *integer_classes
|
25
|
+
value
|
26
|
+
else
|
27
|
+
value.dup
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# Lists the classes Ruby uses for integers
|
32
|
+
#
|
33
|
+
# @api private
|
34
|
+
# @return [Array<Class>]
|
35
|
+
def self.integer_classes
|
36
|
+
@integer_classes ||=
|
37
|
+
if 0.class == Integer
|
38
|
+
[Integer]
|
39
|
+
else
|
40
|
+
[Fixnum, Bignum] # rubocop:disable Lint/UnifiedInteger
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/hashie/version.rb
CHANGED
data/lib/hashie.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'hashie/logger'
|
1
2
|
require 'hashie/version'
|
2
3
|
|
3
4
|
module Hashie
|
@@ -7,25 +8,30 @@ module Hashie
|
|
7
8
|
autoload :Mash, 'hashie/mash'
|
8
9
|
autoload :Trash, 'hashie/trash'
|
9
10
|
autoload :Rash, 'hashie/rash'
|
11
|
+
autoload :Array, 'hashie/array'
|
12
|
+
autoload :Utils, 'hashie/utils'
|
10
13
|
|
11
14
|
module Extensions
|
12
|
-
autoload :Coercion,
|
13
|
-
autoload :DeepMerge,
|
14
|
-
autoload :IgnoreUndeclared,
|
15
|
-
autoload :IndifferentAccess,
|
16
|
-
autoload :MergeInitializer,
|
17
|
-
autoload :MethodAccess,
|
18
|
-
autoload :MethodQuery,
|
19
|
-
autoload :MethodReader,
|
20
|
-
autoload :MethodWriter,
|
21
|
-
autoload :StringifyKeys,
|
22
|
-
autoload :SymbolizeKeys,
|
23
|
-
autoload :DeepFetch,
|
24
|
-
autoload :DeepFind,
|
25
|
-
autoload :DeepLocate,
|
26
|
-
autoload :PrettyInspect,
|
27
|
-
autoload :KeyConversion,
|
15
|
+
autoload :Coercion, 'hashie/extensions/coercion'
|
16
|
+
autoload :DeepMerge, 'hashie/extensions/deep_merge'
|
17
|
+
autoload :IgnoreUndeclared, 'hashie/extensions/ignore_undeclared'
|
18
|
+
autoload :IndifferentAccess, 'hashie/extensions/indifferent_access'
|
19
|
+
autoload :MergeInitializer, 'hashie/extensions/merge_initializer'
|
20
|
+
autoload :MethodAccess, 'hashie/extensions/method_access'
|
21
|
+
autoload :MethodQuery, 'hashie/extensions/method_access'
|
22
|
+
autoload :MethodReader, 'hashie/extensions/method_access'
|
23
|
+
autoload :MethodWriter, 'hashie/extensions/method_access'
|
24
|
+
autoload :StringifyKeys, 'hashie/extensions/stringify_keys'
|
25
|
+
autoload :SymbolizeKeys, 'hashie/extensions/symbolize_keys'
|
26
|
+
autoload :DeepFetch, 'hashie/extensions/deep_fetch'
|
27
|
+
autoload :DeepFind, 'hashie/extensions/deep_find'
|
28
|
+
autoload :DeepLocate, 'hashie/extensions/deep_locate'
|
29
|
+
autoload :PrettyInspect, 'hashie/extensions/pretty_inspect'
|
30
|
+
autoload :KeyConversion, 'hashie/extensions/key_conversion'
|
28
31
|
autoload :MethodAccessWithOverride, 'hashie/extensions/method_access'
|
32
|
+
autoload :StrictKeyAccess, 'hashie/extensions/strict_key_access'
|
33
|
+
autoload :RubyVersion, 'hashie/extensions/ruby_version'
|
34
|
+
autoload :RubyVersionCheck, 'hashie/extensions/ruby_version_check'
|
29
35
|
|
30
36
|
module Parsers
|
31
37
|
autoload :YamlErbParser, 'hashie/extensions/parsers/yaml_erb_parser'
|
@@ -34,10 +40,20 @@ module Hashie
|
|
34
40
|
module Dash
|
35
41
|
autoload :IndifferentAccess, 'hashie/extensions/dash/indifferent_access'
|
36
42
|
autoload :PropertyTranslation, 'hashie/extensions/dash/property_translation'
|
43
|
+
autoload :Coercion, 'hashie/extensions/dash/coercion'
|
44
|
+
autoload :PredefinedValues, 'hashie/extensions/dash/predefined_values'
|
37
45
|
end
|
38
46
|
|
39
47
|
module Mash
|
48
|
+
autoload :KeepOriginalKeys, 'hashie/extensions/mash/keep_original_keys'
|
49
|
+
autoload :PermissiveRespondTo, 'hashie/extensions/mash/permissive_respond_to'
|
40
50
|
autoload :SafeAssignment, 'hashie/extensions/mash/safe_assignment'
|
51
|
+
autoload :SymbolizeKeys, 'hashie/extensions/mash/symbolize_keys'
|
52
|
+
autoload :DefineAccessors, 'hashie/extensions/mash/define_accessors'
|
53
|
+
end
|
54
|
+
|
55
|
+
module Array
|
56
|
+
autoload :PrettyInspect, 'hashie/extensions/array/pretty_inspect'
|
41
57
|
end
|
42
58
|
end
|
43
59
|
|
@@ -45,4 +61,6 @@ module Hashie
|
|
45
61
|
include Hashie::Extensions::StringifyKeys::ClassMethods
|
46
62
|
include Hashie::Extensions::SymbolizeKeys::ClassMethods
|
47
63
|
end
|
64
|
+
|
65
|
+
require 'hashie/railtie' if defined?(::Rails)
|
48
66
|
end
|