hashie 3.6.0 → 4.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +228 -174
- data/CONTRIBUTING.md +13 -6
- data/README.md +127 -15
- data/UPGRADING.md +83 -7
- data/hashie.gemspec +13 -7
- data/lib/hashie.rb +21 -19
- data/lib/hashie/dash.rb +2 -1
- data/lib/hashie/extensions/active_support/core_ext/hash.rb +14 -0
- data/lib/hashie/extensions/coercion.rb +23 -16
- data/lib/hashie/extensions/dash/indifferent_access.rb +20 -1
- data/lib/hashie/extensions/dash/property_translation.rb +6 -3
- data/lib/hashie/extensions/deep_fetch.rb +4 -2
- data/lib/hashie/extensions/deep_find.rb +12 -3
- data/lib/hashie/extensions/deep_locate.rb +22 -7
- data/lib/hashie/extensions/deep_merge.rb +18 -1
- data/lib/hashie/extensions/indifferent_access.rb +1 -3
- 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 +2 -1
- 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/method_access.rb +5 -2
- data/lib/hashie/extensions/parsers/yaml_erb_parser.rb +26 -4
- data/lib/hashie/extensions/ruby_version_check.rb +5 -1
- data/lib/hashie/extensions/strict_key_access.rb +8 -4
- data/lib/hashie/hash.rb +16 -9
- data/lib/hashie/mash.rb +114 -53
- data/lib/hashie/railtie.rb +7 -0
- data/lib/hashie/rash.rb +1 -1
- data/lib/hashie/utils.rb +28 -0
- data/lib/hashie/version.rb +1 -1
- metadata +19 -130
- data/spec/hashie/array_spec.rb +0 -29
- data/spec/hashie/clash_spec.rb +0 -70
- data/spec/hashie/dash_spec.rb +0 -598
- data/spec/hashie/extensions/autoload_spec.rb +0 -24
- data/spec/hashie/extensions/coercion_spec.rb +0 -639
- 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 -295
- 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 -226
- 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 -771
- 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 -328
- 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/elasticsearch/integration_spec.rb +0 -40
- data/spec/integration/omniauth-oauth2/app.rb +0 -52
- data/spec/integration/omniauth-oauth2/integration_spec.rb +0 -26
- data/spec/integration/omniauth-oauth2/some_site.rb +0 -38
- data/spec/integration/omniauth/app.rb +0 -11
- data/spec/integration/omniauth/integration_spec.rb +0 -38
- data/spec/integration/rails-without-dependency/integration_spec.rb +0 -15
- data/spec/integration/rails/app.rb +0 -47
- data/spec/integration/rails/integration_spec.rb +0 -26
- 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
@@ -15,7 +15,8 @@ module Hashie
|
|
15
15
|
# mash[:symbol_key] == mash['symbol_key'] #=> true
|
16
16
|
module KeepOriginalKeys
|
17
17
|
def self.included(descendant)
|
18
|
-
|
18
|
+
error_message = "#{descendant} is not a kind of Hashie::Mash"
|
19
|
+
raise ArgumentError, error_message unless descendant <= Hashie::Mash
|
19
20
|
end
|
20
21
|
|
21
22
|
private
|
@@ -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
|
|
@@ -73,7 +73,9 @@ module Hashie
|
|
73
73
|
end
|
74
74
|
|
75
75
|
def method_missing(name, *args)
|
76
|
-
|
76
|
+
if args.size == 1 && name.to_s =~ /(.*)=$/
|
77
|
+
return self[convert_key(Regexp.last_match[1])] = args.first
|
78
|
+
end
|
77
79
|
|
78
80
|
super
|
79
81
|
end
|
@@ -231,7 +233,8 @@ module Hashie
|
|
231
233
|
# underscores.
|
232
234
|
module MethodAccessWithOverride
|
233
235
|
def self.included(base)
|
234
|
-
[MethodReader, MethodOverridingWriter,
|
236
|
+
[MethodReader, MethodOverridingWriter,
|
237
|
+
MethodQuery, MethodOverridingInitializer].each do |mod|
|
235
238
|
base.send :include, mod
|
236
239
|
end
|
237
240
|
end
|
@@ -6,19 +6,41 @@ module Hashie
|
|
6
6
|
module Extensions
|
7
7
|
module Parsers
|
8
8
|
class YamlErbParser
|
9
|
-
def initialize(file_path)
|
9
|
+
def initialize(file_path, options = {})
|
10
10
|
@content = File.read(file_path)
|
11
11
|
@file_path = file_path.is_a?(Pathname) ? file_path.to_s : file_path
|
12
|
+
@options = options
|
12
13
|
end
|
13
14
|
|
14
15
|
def perform
|
15
16
|
template = ERB.new(@content)
|
16
17
|
template.filename = @file_path
|
17
|
-
|
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)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.perform(file_path, options = {})
|
26
|
+
new(file_path, options).perform
|
18
27
|
end
|
19
28
|
|
20
|
-
|
21
|
-
|
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
|
22
44
|
end
|
23
45
|
end
|
24
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
|
|
data/lib/hashie/hash.rb
CHANGED
@@ -18,20 +18,21 @@ module Hashie
|
|
18
18
|
def to_hash(options = {})
|
19
19
|
out = {}
|
20
20
|
each_key do |k|
|
21
|
-
assignment_key =
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
21
|
+
assignment_key =
|
22
|
+
if options[:stringify_keys]
|
23
|
+
k.to_s
|
24
|
+
elsif options[:symbolize_keys]
|
25
|
+
k.to_s.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] << (array_object
|
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,6 +45,12 @@ 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
55
|
if object.method(:to_hash).arity.zero?
|
49
56
|
object.to_hash
|
data/lib/hashie/mash.rb
CHANGED
@@ -2,6 +2,7 @@ require 'hashie/hash'
|
|
2
2
|
require 'hashie/array'
|
3
3
|
require 'hashie/utils'
|
4
4
|
require 'hashie/logger'
|
5
|
+
require 'hashie/extensions/key_conflict_warning'
|
5
6
|
|
6
7
|
module Hashie
|
7
8
|
# Mash allows you to create pseudo-objects that have method-like
|
@@ -15,9 +16,12 @@ module Hashie
|
|
15
16
|
#
|
16
17
|
# * No punctuation: Returns the value of the hash for that key, or nil if none exists.
|
17
18
|
# * Assignment (<tt>=</tt>): Sets the attribute of the given method name.
|
18
|
-
# *
|
19
|
-
#
|
20
|
-
# *
|
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.
|
21
25
|
#
|
22
26
|
# == Basic Example
|
23
27
|
#
|
@@ -60,49 +64,19 @@ module Hashie
|
|
60
64
|
class Mash < Hash
|
61
65
|
include Hashie::Extensions::PrettyInspect
|
62
66
|
include Hashie::Extensions::RubyVersionCheck
|
67
|
+
extend Hashie::Extensions::KeyConflictWarning
|
63
68
|
|
64
69
|
ALLOWED_SUFFIXES = %w[? ! = _].freeze
|
65
70
|
|
66
|
-
class CannotDisableMashWarnings < StandardError
|
67
|
-
def initialize(message = 'You cannot disable warnings on the base Mash class. Please subclass the Mash and disable it in the subclass.')
|
68
|
-
super(message)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
# Disable the logging of warnings based on keys conflicting keys/methods
|
73
|
-
#
|
74
|
-
# @api semipublic
|
75
|
-
# @return [void]
|
76
|
-
def self.disable_warnings
|
77
|
-
raise CannotDisableMashWarnings if self == Hashie::Mash
|
78
|
-
@disable_warnings = true
|
79
|
-
end
|
80
|
-
|
81
|
-
# Checks whether this class disables warnings for conflicting keys/methods
|
82
|
-
#
|
83
|
-
# @api semipublic
|
84
|
-
# @return [Boolean]
|
85
|
-
def self.disable_warnings?
|
86
|
-
@disable_warnings ||= false
|
87
|
-
end
|
88
|
-
|
89
|
-
# Inheritance hook that sets class configuration when inherited.
|
90
|
-
#
|
91
|
-
# @api semipublic
|
92
|
-
# @return [void]
|
93
|
-
def self.inherited(subclass)
|
94
|
-
super
|
95
|
-
subclass.disable_warnings if disable_warnings?
|
96
|
-
end
|
97
|
-
|
98
71
|
def self.load(path, options = {})
|
99
72
|
@_mashes ||= new
|
100
73
|
|
101
74
|
return @_mashes[path] if @_mashes.key?(path)
|
102
75
|
raise ArgumentError, "The following file doesn't exist: #{path}" unless File.file?(path)
|
103
76
|
|
104
|
-
|
105
|
-
|
77
|
+
options = options.dup
|
78
|
+
parser = options.delete(:parser) { Hashie::Extensions::Parsers::YamlErbParser }
|
79
|
+
@_mashes[path] = new(parser.perform(path, options)).freeze
|
106
80
|
end
|
107
81
|
|
108
82
|
def to_module(mash_method_name = :settings)
|
@@ -114,6 +88,10 @@ module Hashie
|
|
114
88
|
end
|
115
89
|
end
|
116
90
|
|
91
|
+
def with_accessors!
|
92
|
+
extend Hashie::Extensions::Mash::DefineAccessors
|
93
|
+
end
|
94
|
+
|
117
95
|
alias to_s inspect
|
118
96
|
|
119
97
|
# If you pass in an existing hash, it will
|
@@ -125,6 +103,19 @@ module Hashie
|
|
125
103
|
default ? super(default) : super(&blk)
|
126
104
|
end
|
127
105
|
|
106
|
+
# Creates a new anonymous subclass with key conflict
|
107
|
+
# warnings disabled. You may pass an array of method
|
108
|
+
# symbols to restrict the disabled warnings to.
|
109
|
+
# Hashie::Mash.quiet.new(hash) all warnings disabled.
|
110
|
+
# Hashie::Mash.quiet(:zip).new(hash) only zip warning
|
111
|
+
# is disabled.
|
112
|
+
def self.quiet(*method_keys)
|
113
|
+
@memoized_classes ||= {}
|
114
|
+
@memoized_classes[method_keys] ||= Class.new(self) do
|
115
|
+
disable_warnings(*method_keys)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
128
119
|
class << self; alias [] new; end
|
129
120
|
|
130
121
|
alias regular_reader []
|
@@ -183,6 +174,25 @@ module Hashie
|
|
183
174
|
super(*keys.map { |key| convert_key(key) })
|
184
175
|
end
|
185
176
|
|
177
|
+
# Returns a new instance of the class it was called on, using its keys as
|
178
|
+
# values, and its values as keys. The new values and keys will always be
|
179
|
+
# strings.
|
180
|
+
def invert
|
181
|
+
self.class.new(super)
|
182
|
+
end
|
183
|
+
|
184
|
+
# Returns a new instance of the class it was called on, containing elements
|
185
|
+
# for which the given block returns false.
|
186
|
+
def reject(&blk)
|
187
|
+
self.class.new(super(&blk))
|
188
|
+
end
|
189
|
+
|
190
|
+
# Returns a new instance of the class it was called on, containing elements
|
191
|
+
# for which the given block returns true.
|
192
|
+
def select(&blk)
|
193
|
+
self.class.new(super(&blk))
|
194
|
+
end
|
195
|
+
|
186
196
|
alias regular_dup dup
|
187
197
|
# Duplicates the current mash as a new mash.
|
188
198
|
def dup
|
@@ -197,19 +207,47 @@ module Hashie
|
|
197
207
|
alias include? key?
|
198
208
|
alias member? key?
|
199
209
|
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
210
|
+
if with_minimum_ruby?('2.6.0')
|
211
|
+
# Performs a deep_update on a duplicate of the
|
212
|
+
# current mash.
|
213
|
+
def deep_merge(*other_hashes, &blk)
|
214
|
+
dup.deep_update(*other_hashes, &blk)
|
215
|
+
end
|
216
|
+
|
217
|
+
# Recursively merges this mash with the passed
|
218
|
+
# in hash, merging each hash in the hierarchy.
|
219
|
+
def deep_update(*other_hashes, &blk)
|
220
|
+
other_hashes.each do |other_hash|
|
221
|
+
_deep_update(other_hash, &blk)
|
222
|
+
end
|
223
|
+
self
|
224
|
+
end
|
225
|
+
else
|
226
|
+
# Performs a deep_update on a duplicate of the
|
227
|
+
# current mash.
|
228
|
+
def deep_merge(other_hash, &blk)
|
229
|
+
dup.deep_update(other_hash, &blk)
|
230
|
+
end
|
231
|
+
|
232
|
+
# Recursively merges this mash with the passed
|
233
|
+
# in hash, merging each hash in the hierarchy.
|
234
|
+
def deep_update(other_hash, &blk)
|
235
|
+
_deep_update(other_hash, &blk)
|
236
|
+
self
|
237
|
+
end
|
204
238
|
end
|
239
|
+
|
240
|
+
# Alias these lexically so they get the correctly defined
|
241
|
+
# #deep_merge and #deep_update based on ruby version.
|
205
242
|
alias merge deep_merge
|
243
|
+
alias deep_merge! deep_update
|
244
|
+
alias update deep_update
|
245
|
+
alias merge! update
|
206
246
|
|
207
|
-
|
208
|
-
# in hash, merging each hash in the hierarchy.
|
209
|
-
def deep_update(other_hash, &blk)
|
247
|
+
def _deep_update(other_hash, &blk)
|
210
248
|
other_hash.each_pair do |k, v|
|
211
249
|
key = convert_key(k)
|
212
|
-
if
|
250
|
+
if v.is_a?(::Hash) && key?(key) && regular_reader(key).is_a?(Mash)
|
213
251
|
custom_reader(key).deep_update(v, &blk)
|
214
252
|
else
|
215
253
|
value = convert_value(v, true)
|
@@ -217,11 +255,8 @@ module Hashie
|
|
217
255
|
custom_writer(key, value, false)
|
218
256
|
end
|
219
257
|
end
|
220
|
-
self
|
221
258
|
end
|
222
|
-
|
223
|
-
alias update deep_update
|
224
|
-
alias merge! update
|
259
|
+
private :_deep_update
|
225
260
|
|
226
261
|
# Assigns a value to a key
|
227
262
|
def assign_property(name, value)
|
@@ -296,6 +331,29 @@ module Hashie
|
|
296
331
|
end
|
297
332
|
end
|
298
333
|
|
334
|
+
with_minimum_ruby('2.4.0') do
|
335
|
+
def transform_values(&blk)
|
336
|
+
self.class.new(super(&blk))
|
337
|
+
end
|
338
|
+
|
339
|
+
# Returns a new instance of the class it was called on, with nil values
|
340
|
+
# removed.
|
341
|
+
def compact
|
342
|
+
self.class.new(super)
|
343
|
+
end
|
344
|
+
end
|
345
|
+
|
346
|
+
with_minimum_ruby('2.5.0') do
|
347
|
+
def slice(*keys)
|
348
|
+
string_keys = keys.map { |key| convert_key(key) }
|
349
|
+
self.class.new(super(*string_keys))
|
350
|
+
end
|
351
|
+
|
352
|
+
def transform_keys(&blk)
|
353
|
+
self.class.new(super(&blk))
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
299
357
|
protected
|
300
358
|
|
301
359
|
def method_name_and_suffix(method_name)
|
@@ -325,8 +383,6 @@ module Hashie
|
|
325
383
|
when ::Hash
|
326
384
|
val = val.dup if duping
|
327
385
|
self.class.new(val)
|
328
|
-
when Array
|
329
|
-
val.map { |e| convert_value(e) }
|
330
386
|
when ::Array
|
331
387
|
Array.new(val.map { |e| convert_value(e) })
|
332
388
|
else
|
@@ -337,7 +393,7 @@ module Hashie
|
|
337
393
|
private
|
338
394
|
|
339
395
|
def log_built_in_message(method_key)
|
340
|
-
return if self.class.disable_warnings?
|
396
|
+
return if self.class.disable_warnings?(method_key)
|
341
397
|
|
342
398
|
method_information = Hashie::Utils.method_information(method(method_key))
|
343
399
|
|
@@ -350,7 +406,12 @@ module Hashie
|
|
350
406
|
end
|
351
407
|
|
352
408
|
def log_collision?(method_key)
|
353
|
-
respond_to?(method_key)
|
409
|
+
return unless respond_to?(method_key)
|
410
|
+
|
411
|
+
_, suffix = method_name_and_suffix(method_key)
|
412
|
+
|
413
|
+
(!suffix || suffix == '='.freeze) &&
|
414
|
+
!self.class.disable_warnings?(method_key) &&
|
354
415
|
!(regular_key?(method_key) || regular_key?(method_key.to_s))
|
355
416
|
end
|
356
417
|
end
|