hashie 2.1.2 → 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 +7 -0
- data/CHANGELOG.md +524 -59
- data/CONTRIBUTING.md +24 -7
- data/README.md +781 -90
- data/Rakefile +19 -2
- data/UPGRADING.md +245 -0
- data/hashie.gemspec +21 -13
- data/lib/hashie.rb +60 -21
- data/lib/hashie/array.rb +21 -0
- data/lib/hashie/clash.rb +24 -12
- data/lib/hashie/dash.rb +96 -33
- 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 +124 -18
- data/lib/hashie/extensions/dash/coercion.rb +25 -0
- data/lib/hashie/extensions/dash/indifferent_access.rb +56 -0
- data/lib/hashie/extensions/dash/property_translation.rb +191 -0
- data/lib/hashie/extensions/deep_fetch.rb +7 -5
- data/lib/hashie/extensions/deep_find.rb +69 -0
- data/lib/hashie/extensions/deep_locate.rb +113 -0
- data/lib/hashie/extensions/deep_merge.rb +35 -12
- data/lib/hashie/extensions/ignore_undeclared.rb +11 -5
- data/lib/hashie/extensions/indifferent_access.rb +28 -16
- data/lib/hashie/extensions/key_conflict_warning.rb +55 -0
- data/lib/hashie/extensions/key_conversion.rb +0 -82
- 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 +18 -0
- data/lib/hashie/extensions/mash/symbolize_keys.rb +38 -0
- data/lib/hashie/extensions/method_access.rb +154 -11
- data/lib/hashie/extensions/parsers/yaml_erb_parser.rb +48 -0
- data/lib/hashie/extensions/pretty_inspect.rb +19 -0
- 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 +71 -0
- data/lib/hashie/extensions/symbolize_keys.rb +71 -0
- data/lib/hashie/hash.rb +27 -8
- data/lib/hashie/logger.rb +18 -0
- data/lib/hashie/mash.rb +235 -57
- data/lib/hashie/railtie.rb +21 -0
- data/lib/hashie/rash.rb +40 -16
- data/lib/hashie/trash.rb +2 -88
- data/lib/hashie/utils.rb +44 -0
- data/lib/hashie/version.rb +1 -1
- metadata +42 -81
- data/.gitignore +0 -9
- data/.rspec +0 -2
- data/.rubocop.yml +0 -36
- data/.travis.yml +0 -15
- data/Gemfile +0 -11
- data/Guardfile +0 -5
- data/lib/hashie/hash_extensions.rb +0 -47
- data/spec/hashie/clash_spec.rb +0 -48
- data/spec/hashie/dash_spec.rb +0 -338
- data/spec/hashie/extensions/coercion_spec.rb +0 -156
- data/spec/hashie/extensions/deep_fetch_spec.rb +0 -70
- data/spec/hashie/extensions/deep_merge_spec.rb +0 -22
- data/spec/hashie/extensions/ignore_undeclared_spec.rb +0 -23
- data/spec/hashie/extensions/indifferent_access_spec.rb +0 -152
- data/spec/hashie/extensions/key_conversion_spec.rb +0 -103
- data/spec/hashie/extensions/merge_initializer_spec.rb +0 -23
- data/spec/hashie/extensions/method_access_spec.rb +0 -121
- data/spec/hashie/hash_spec.rb +0 -66
- data/spec/hashie/mash_spec.rb +0 -467
- data/spec/hashie/rash_spec.rb +0 -44
- data/spec/hashie/trash_spec.rb +0 -193
- data/spec/hashie/version_spec.rb +0 -7
- data/spec/spec.opts +0 -3
- data/spec/spec_helper.rb +0 -8
data/Rakefile
CHANGED
@@ -7,9 +7,26 @@ Bundler::GemHelper.install_tasks
|
|
7
7
|
require 'rspec/core/rake_task'
|
8
8
|
RSpec::Core::RakeTask.new do |spec|
|
9
9
|
spec.pattern = 'spec/**/*_spec.rb'
|
10
|
+
spec.exclude_pattern = 'spec/integration/**/*_spec.rb'
|
10
11
|
end
|
11
12
|
|
12
13
|
require 'rubocop/rake_task'
|
13
|
-
|
14
|
+
RuboCop::RakeTask.new(:rubocop)
|
14
15
|
|
15
|
-
|
16
|
+
require_relative 'spec/support/integration_specs'
|
17
|
+
task :integration_specs do
|
18
|
+
next if ENV['CI']
|
19
|
+
status_codes = []
|
20
|
+
handler = lambda do |status_code|
|
21
|
+
status_codes << status_code unless status_code.zero?
|
22
|
+
end
|
23
|
+
|
24
|
+
run_all_integration_specs(handler: handler, logger: ->(msg) { puts msg })
|
25
|
+
|
26
|
+
if status_codes.any?
|
27
|
+
warn "#{status_codes.size} integration test(s) failed"
|
28
|
+
exit status_codes.last
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
task default: %i[rubocop spec integration_specs]
|
data/UPGRADING.md
ADDED
@@ -0,0 +1,245 @@
|
|
1
|
+
Upgrading Hashie
|
2
|
+
================
|
3
|
+
|
4
|
+
### Upgrading to 4.0.0
|
5
|
+
|
6
|
+
#### Non-destructive Hash methods called on Mash
|
7
|
+
|
8
|
+
The following non-destructive Hash methods called on Mash will now return an instance of the class it was called on.
|
9
|
+
|
10
|
+
| method | ruby |
|
11
|
+
| ----------------- | ---- |
|
12
|
+
| #compact | |
|
13
|
+
| #invert | |
|
14
|
+
| #reject | |
|
15
|
+
| #select | |
|
16
|
+
| #slice | 2.5 |
|
17
|
+
| #transform_keys | 2.5 |
|
18
|
+
| #transform_values | 2.4 |
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
class Parents < Hashie::Mash; end
|
22
|
+
|
23
|
+
parents = Parents.new(father: 'Dad', mother: 'Mom')
|
24
|
+
cool_parents = parents.transform_values { |v| v + v[-1] + 'io'}
|
25
|
+
|
26
|
+
p cool_parents
|
27
|
+
|
28
|
+
# before:
|
29
|
+
{"father"=>"Daddio", "mother"=>"Mommio"}
|
30
|
+
=> {"father"=>"Daddio", "mother"=>"Mommio"}
|
31
|
+
|
32
|
+
# after:
|
33
|
+
#<Parents father="Daddio" mother="Mommio">
|
34
|
+
=> {"father"=>"Dad", "mother"=>"Mom"}
|
35
|
+
```
|
36
|
+
|
37
|
+
This may make places where you had to re-make the Mash redundant, and may cause unintended side effects if your application was expecting a plain old ruby Hash.
|
38
|
+
|
39
|
+
#### Ruby 2.6: Mash#merge and Mash#merge!
|
40
|
+
|
41
|
+
In Ruby > 2.6.0, Hashie now supports passing multiple hash and Mash objects to Mash#merge and Mash#merge!.
|
42
|
+
|
43
|
+
#### Hashie::Mash::CannotDisableMashWarnings error class is removed
|
44
|
+
|
45
|
+
There shouldn't really be a case that anyone was relying on catching this specific error, but if so, they should change it to rescue Hashie::Extensions::KeyConflictWarning::CannotDisableMashWarnings
|
46
|
+
|
47
|
+
### Upgrading to 3.7.0
|
48
|
+
|
49
|
+
#### Mash#load takes options
|
50
|
+
|
51
|
+
The `Hashie::Mash#load` method now accepts options, changing the interface of `Parser#initialize`. If you have a custom parser, you must update its `initialize` method.
|
52
|
+
|
53
|
+
For example, `Hashie::Extensions::Parsers::YamlErbParser` now accepts `permitted_classes`, `permitted_symbols` and `aliases` options.
|
54
|
+
|
55
|
+
Before:
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
class Hashie::Extensions::Parsers::YamlErbParser
|
59
|
+
def initialize(file_path)
|
60
|
+
@file_path = file_path
|
61
|
+
end
|
62
|
+
end
|
63
|
+
```
|
64
|
+
|
65
|
+
After:
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
class Hashie::Extensions::Parsers::YamlErbParser
|
69
|
+
def initialize(file_path, options = {})
|
70
|
+
@file_path = file_path
|
71
|
+
@options = options
|
72
|
+
end
|
73
|
+
end
|
74
|
+
```
|
75
|
+
|
76
|
+
Options can now be passed into `Mash#load`.
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
Mash.load(filename, permitted_classes: [])
|
80
|
+
```
|
81
|
+
|
82
|
+
### Upgrading to 3.5.2
|
83
|
+
|
84
|
+
#### Disable logging in Mash subclasses
|
85
|
+
|
86
|
+
If you subclass `Hashie::Mash`, you can now disable the logging we do about
|
87
|
+
overriding existing methods with keys. This looks like:
|
88
|
+
|
89
|
+
```ruby
|
90
|
+
class MyMash < Hashie::Mash
|
91
|
+
disable_warnings
|
92
|
+
end
|
93
|
+
```
|
94
|
+
|
95
|
+
### Upgrading to 3.4.7
|
96
|
+
|
97
|
+
#### Procs as default values for Dash
|
98
|
+
|
99
|
+
```ruby
|
100
|
+
class MyHash < Hashie::Dash
|
101
|
+
property :time, default: -> { Time.now }
|
102
|
+
end
|
103
|
+
```
|
104
|
+
|
105
|
+
In versions < 3.4.7 `Time.now` will be evaluated when `time` property is accessed directly first time.
|
106
|
+
In version >= 3.4.7 `Time.now` is evaluated in time of object initialization.
|
107
|
+
### Upgrading to 3.4.4
|
108
|
+
|
109
|
+
#### Mash subclasses and reverse_merge
|
110
|
+
|
111
|
+
```ruby
|
112
|
+
class MyMash < Hashie::Mash
|
113
|
+
end
|
114
|
+
```
|
115
|
+
|
116
|
+
In versions >= 3.4.4 `MyMash#reverse_merge` returns an instance of `MyMash` but in previous versions it was a `Hashie::Mash` instance.
|
117
|
+
|
118
|
+
### Upgrading to 3.2.2
|
119
|
+
|
120
|
+
#### Testing if key defined
|
121
|
+
|
122
|
+
In versions <= 3.2.1 Hash object being questioned doesn't return a boolean value as it's mentioned in README.md
|
123
|
+
|
124
|
+
```ruby
|
125
|
+
class MyHash < Hash
|
126
|
+
include Hashie::Extensions::MethodAccess
|
127
|
+
end
|
128
|
+
|
129
|
+
h = MyHash.new
|
130
|
+
h.abc = 'def'
|
131
|
+
h.abc # => 'def'
|
132
|
+
h.abc? # => 'def'
|
133
|
+
```
|
134
|
+
|
135
|
+
In versions >= 3.2.2 it returns a boolean value
|
136
|
+
|
137
|
+
```ruby
|
138
|
+
h.abc? # => true
|
139
|
+
h.abb? # => false
|
140
|
+
```
|
141
|
+
|
142
|
+
### Upgrading to 3.2.1
|
143
|
+
|
144
|
+
#### Possible coercion changes
|
145
|
+
|
146
|
+
The improvements made to coercions in version 3.2.1 [issue #200](https://github.com/hashie/hashie/pull/200) do not break the documented API, but are significant enough that changes may effect undocumented side-effects. Applications that depended on those side-effects will need to be updated.
|
147
|
+
|
148
|
+
**Change**: Type coercion no longer creates new objects if the input matches the target type. Previously coerced properties always resulted in the creation of a new object, even when it wasn't necessary. This had the effect of a `dup` or `clone` on coerced properties but not uncoerced ones.
|
149
|
+
|
150
|
+
If necessary, `dup` or `clone` your own objects. Do not assume Hashie will do it for you.
|
151
|
+
|
152
|
+
**Change**: Failed coercion attempts now raise Hashie::CoercionError.
|
153
|
+
|
154
|
+
Hashie now raises a Hashie::CoercionError that details on the property that could not be coerced, the source and target type of the coercion, and the internal error. Previously only the internal error was raised.
|
155
|
+
|
156
|
+
Applications that were attempting to rescuing the internal errors should be updated to rescue Hashie::CoercionError instead.
|
157
|
+
|
158
|
+
### Upgrading to 3.0
|
159
|
+
|
160
|
+
#### Compatibility with Rails 4 Strong Parameters
|
161
|
+
|
162
|
+
Version 2.1 introduced support to prevent default Rails 4 mass-assignment protection behavior. This was [issue #89](https://github.com/hashie/hashie/issues/89), resolved in [#104](https://github.com/hashie/hashie/pull/104). In version 2.2 this behavior has been removed in [#147](https://github.com/hashie/hashie/pull/147) in favor of a mixin and finally extracted into a separate gem in Hashie 3.0.
|
163
|
+
|
164
|
+
To enable 2.1 compatible behavior with Rails 4, use the [hashie_rails](http://rubygems.org/gems/hashie_rails) gem.
|
165
|
+
|
166
|
+
```
|
167
|
+
gem 'hashie_rails'
|
168
|
+
```
|
169
|
+
|
170
|
+
See [#154](https://github.com/hashie/hashie/pull/154) and [Mash and Rails 4 Strong Parameters](README.md#mash-and-rails-4-strong-parameters) for more details.
|
171
|
+
|
172
|
+
#### Key Conversions in Hashie::Dash and Hashie::Trash
|
173
|
+
|
174
|
+
Version 2.1 and older of Hashie::Dash and Hashie::Trash converted keys to strings by default. This is no longer the case in 2.2.
|
175
|
+
|
176
|
+
Consider the following code.
|
177
|
+
|
178
|
+
```ruby
|
179
|
+
class Person < Hashie::Dash
|
180
|
+
property :name
|
181
|
+
end
|
182
|
+
|
183
|
+
p = Person.new(name: 'dB.')
|
184
|
+
```
|
185
|
+
|
186
|
+
Version 2.1 behaves as follows.
|
187
|
+
|
188
|
+
```ruby
|
189
|
+
p.name # => 'dB.'
|
190
|
+
p[:name] # => 'dB.'
|
191
|
+
p['name'] # => 'dB.'
|
192
|
+
|
193
|
+
# not what I put in
|
194
|
+
p.inspect # => { 'name' => 'dB.' }
|
195
|
+
p.to_hash # => { 'name' => 'dB.' }
|
196
|
+
```
|
197
|
+
|
198
|
+
It was not possible to achieve the behavior of preserving keys, as described in [issue #151](https://github.com/hashie/hashie/issues/151).
|
199
|
+
|
200
|
+
Version 2.2 does not perform this conversion by default.
|
201
|
+
|
202
|
+
```ruby
|
203
|
+
p.name # => 'dB.'
|
204
|
+
p[:name] # => 'dB.'
|
205
|
+
# p['name'] # => NoMethodError
|
206
|
+
|
207
|
+
p.inspect # => { :name => 'dB.' }
|
208
|
+
p.to_hash # => { :name => 'dB.' }
|
209
|
+
```
|
210
|
+
|
211
|
+
To enable behavior compatible with older versions, use `Hashie::Extensions::Dash::IndifferentAccess`.
|
212
|
+
|
213
|
+
```ruby
|
214
|
+
class Person < Hashie::Dash
|
215
|
+
include Hashie::Extensions::Dash::IndifferentAccess
|
216
|
+
property :name
|
217
|
+
end
|
218
|
+
```
|
219
|
+
|
220
|
+
#### Key Conversions in Hashie::Hash#to_hash
|
221
|
+
|
222
|
+
Version 2.1 or older of Hash#to_hash converted keys to strings automatically.
|
223
|
+
|
224
|
+
```ruby
|
225
|
+
instance = Hashie::Hash[first: 'First', 'last' => 'Last']
|
226
|
+
instance.to_hash # => { "first" => 'First', "last" => 'Last' }
|
227
|
+
```
|
228
|
+
|
229
|
+
It was possible to symbolize keys by passing `:symbolize_keys`, however it was not possible to retrieve the hash with initial key values.
|
230
|
+
|
231
|
+
```ruby
|
232
|
+
instance.to_hash(symbolize_keys: true) # => { :first => 'First', :last => 'Last' }
|
233
|
+
instance.to_hash(stringify_keys: true) # => { "first" => 'First', "last" => 'Last' }
|
234
|
+
```
|
235
|
+
|
236
|
+
Version 2.2 no longer converts keys by default.
|
237
|
+
|
238
|
+
```ruby
|
239
|
+
instance = Hashie::Hash[first: 'First', 'last' => 'Last']
|
240
|
+
instance.to_hash # => { :first => 'First', "last" => 'Last' }
|
241
|
+
```
|
242
|
+
|
243
|
+
The behavior with `symbolize_keys` and `stringify_keys` is unchanged.
|
244
|
+
|
245
|
+
See [#152](https://github.com/hashie/hashie/pull/152) for more information.
|
data/hashie.gemspec
CHANGED
@@ -1,20 +1,28 @@
|
|
1
1
|
require File.expand_path('../lib/hashie/version', __FILE__)
|
2
2
|
|
3
3
|
Gem::Specification.new do |gem|
|
4
|
-
gem.
|
5
|
-
gem.
|
6
|
-
gem.
|
7
|
-
gem.
|
8
|
-
gem.
|
4
|
+
gem.name = 'hashie'
|
5
|
+
gem.version = Hashie::VERSION
|
6
|
+
gem.authors = ['Michael Bleigh', 'Jerry Cheung']
|
7
|
+
gem.email = ['michael@intridea.com', 'jollyjerry@gmail.com']
|
8
|
+
gem.description = 'Hashie is a collection of classes and mixins that make hashes more powerful.'
|
9
|
+
gem.summary = 'Your friendly neighborhood hash library.'
|
10
|
+
gem.homepage = 'https://github.com/hashie/hashie'
|
11
|
+
gem.license = 'MIT'
|
9
12
|
|
10
|
-
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
11
|
-
gem.files = `git ls-files`.split("\n")
|
12
|
-
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
13
|
-
gem.name = "hashie"
|
14
13
|
gem.require_paths = ['lib']
|
15
|
-
gem.
|
16
|
-
gem.
|
14
|
+
gem.files = %w[.yardopts CHANGELOG.md CONTRIBUTING.md LICENSE README.md UPGRADING.md]
|
15
|
+
gem.files += %w[Rakefile hashie.gemspec]
|
16
|
+
gem.files += Dir['lib/**/*.rb']
|
17
|
+
|
18
|
+
if gem.respond_to?(:metadata)
|
19
|
+
gem.metadata = {
|
20
|
+
'bug_tracker_uri' => 'https://github.com/hashie/hashie/issues',
|
21
|
+
'changelog_uri' => 'https://github.com/hashie/hashie/blob/master/CHANGELOG.md',
|
22
|
+
'documentation_uri' => 'https://www.rubydoc.info/gems/hashie',
|
23
|
+
'source_code_uri' => 'https://github.com/hashie/hashie'
|
24
|
+
}
|
25
|
+
end
|
17
26
|
|
18
|
-
gem.add_development_dependency '
|
19
|
-
gem.add_development_dependency 'rspec'
|
27
|
+
gem.add_development_dependency 'bundler'
|
20
28
|
end
|
data/lib/hashie.rb
CHANGED
@@ -1,26 +1,65 @@
|
|
1
|
+
require 'hashie/logger'
|
2
|
+
require 'hashie/version'
|
3
|
+
|
1
4
|
module Hashie
|
2
|
-
autoload :Clash,
|
3
|
-
autoload :Dash,
|
4
|
-
autoload :Hash,
|
5
|
-
autoload :
|
6
|
-
autoload :
|
7
|
-
autoload :
|
8
|
-
autoload :
|
9
|
-
autoload :
|
5
|
+
autoload :Clash, 'hashie/clash'
|
6
|
+
autoload :Dash, 'hashie/dash'
|
7
|
+
autoload :Hash, 'hashie/hash'
|
8
|
+
autoload :Mash, 'hashie/mash'
|
9
|
+
autoload :Trash, 'hashie/trash'
|
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 :
|
15
|
-
autoload :
|
16
|
-
autoload :
|
17
|
-
autoload :
|
18
|
-
autoload :
|
19
|
-
autoload :
|
20
|
-
autoload :
|
21
|
-
autoload :
|
22
|
-
autoload :
|
23
|
-
autoload :
|
24
|
-
autoload :
|
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'
|
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'
|
35
|
+
|
36
|
+
module Parsers
|
37
|
+
autoload :YamlErbParser, 'hashie/extensions/parsers/yaml_erb_parser'
|
38
|
+
end
|
39
|
+
|
40
|
+
module Dash
|
41
|
+
autoload :IndifferentAccess, 'hashie/extensions/dash/indifferent_access'
|
42
|
+
autoload :PropertyTranslation, 'hashie/extensions/dash/property_translation'
|
43
|
+
autoload :Coercion, 'hashie/extensions/dash/coercion'
|
44
|
+
end
|
45
|
+
|
46
|
+
module Mash
|
47
|
+
autoload :KeepOriginalKeys, 'hashie/extensions/mash/keep_original_keys'
|
48
|
+
autoload :PermissiveRespondTo, 'hashie/extensions/mash/permissive_respond_to'
|
49
|
+
autoload :SafeAssignment, 'hashie/extensions/mash/safe_assignment'
|
50
|
+
autoload :SymbolizeKeys, 'hashie/extensions/mash/symbolize_keys'
|
51
|
+
autoload :DefineAccessors, 'hashie/extensions/mash/define_accessors'
|
52
|
+
end
|
53
|
+
|
54
|
+
module Array
|
55
|
+
autoload :PrettyInspect, 'hashie/extensions/array/pretty_inspect'
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
class << self
|
60
|
+
include Hashie::Extensions::StringifyKeys::ClassMethods
|
61
|
+
include Hashie::Extensions::SymbolizeKeys::ClassMethods
|
25
62
|
end
|
63
|
+
|
64
|
+
require 'hashie/railtie' if defined?(::Rails)
|
26
65
|
end
|
data/lib/hashie/array.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'hashie/extensions/array/pretty_inspect'
|
2
|
+
require 'hashie/extensions/ruby_version_check'
|
3
|
+
|
4
|
+
module Hashie
|
5
|
+
class Array < ::Array
|
6
|
+
include Hashie::Extensions::Array::PrettyInspect
|
7
|
+
include Hashie::Extensions::RubyVersionCheck
|
8
|
+
with_minimum_ruby('2.3.0') do
|
9
|
+
def dig(*indexes)
|
10
|
+
converted_indexes = indexes.map do |idx|
|
11
|
+
begin
|
12
|
+
Integer(idx)
|
13
|
+
rescue ArgumentError
|
14
|
+
idx
|
15
|
+
end
|
16
|
+
end
|
17
|
+
super(*converted_indexes)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/hashie/clash.rb
CHANGED
@@ -54,7 +54,7 @@ module Hashie
|
|
54
54
|
case args.length
|
55
55
|
when 1
|
56
56
|
val = args.first
|
57
|
-
val = self[key].merge(val) if self[key].is_a?(::Hash) && val.is_a?(::Hash)
|
57
|
+
val = self.class.new(self[key]).merge(val) if self[key].is_a?(::Hash) && val.is_a?(::Hash)
|
58
58
|
else
|
59
59
|
val = args
|
60
60
|
end
|
@@ -64,22 +64,34 @@ module Hashie
|
|
64
64
|
end
|
65
65
|
|
66
66
|
def method_missing(name, *args) #:nodoc:
|
67
|
-
|
68
|
-
if name.match(/!$/) && args.empty?
|
67
|
+
if args.empty? && name.to_s.end_with?('!')
|
69
68
|
key = name[0...-1].to_sym
|
70
69
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
70
|
+
case self[key]
|
71
|
+
when NilClass
|
72
|
+
self[key] = self.class.new({}, self)
|
73
|
+
when Clash
|
74
|
+
self[key]
|
75
|
+
when Hash
|
76
|
+
self[key] = self.class.new(self[key], self)
|
75
77
|
else
|
76
|
-
|
78
|
+
raise ChainError, 'Tried to chain into a non-hash key.'
|
77
79
|
end
|
78
|
-
|
79
|
-
self[key]
|
80
80
|
elsif args.any?
|
81
|
-
|
82
|
-
|
81
|
+
merge_store(name, *args)
|
82
|
+
else
|
83
|
+
super
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def respond_to_missing?(method_name, _include_private = false)
|
88
|
+
method_name = method_name.to_s
|
89
|
+
|
90
|
+
if method_name.end_with?('!')
|
91
|
+
key = method_name[0...-1].to_sym
|
92
|
+
[NilClass, Clash, Hash].include?(self[key].class)
|
93
|
+
else
|
94
|
+
true
|
83
95
|
end
|
84
96
|
end
|
85
97
|
end
|