hashie 2.1.2 → 4.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|