hashie 3.6.0 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +28 -0
- data/README.md +95 -7
- data/UPGRADING.md +78 -2
- data/hashie.gemspec +2 -1
- data/lib/hashie.rb +20 -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 +5 -2
- 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/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/safe_assignment.rb +3 -1
- data/lib/hashie/extensions/method_access.rb +5 -2
- data/lib/hashie/extensions/parsers/yaml_erb_parser.rb +9 -4
- data/lib/hashie/extensions/strict_key_access.rb +8 -4
- data/lib/hashie/hash.rb +16 -9
- data/lib/hashie/mash.rb +99 -43
- data/lib/hashie/railtie.rb +7 -0
- data/lib/hashie/rash.rb +1 -1
- data/lib/hashie/version.rb +1 -1
- data/spec/hashie/dash_spec.rb +18 -8
- data/spec/hashie/extensions/coercion_spec.rb +17 -8
- data/spec/hashie/extensions/deep_find_spec.rb +12 -6
- data/spec/hashie/extensions/deep_locate_spec.rb +2 -1
- data/spec/hashie/extensions/deep_merge_spec.rb +6 -2
- data/spec/hashie/extensions/ignore_undeclared_spec.rb +2 -1
- data/spec/hashie/extensions/mash/define_accessors_spec.rb +90 -0
- data/spec/hashie/extensions/method_access_spec.rb +8 -1
- data/spec/hashie/extensions/strict_key_access_spec.rb +9 -10
- data/spec/hashie/extensions/symbolize_keys_spec.rb +3 -1
- data/spec/hashie/hash_spec.rb +45 -6
- data/spec/hashie/mash_spec.rb +314 -8
- data/spec/hashie/trash_spec.rb +9 -3
- data/spec/integration/elasticsearch/integration_spec.rb +3 -2
- data/spec/integration/rails/app.rb +5 -12
- data/spec/integration/rails/integration_spec.rb +22 -1
- metadata +8 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8aa4350423b73820353dc1e15eeff8f6dee0325534e008bec7a2986313673df2
|
4
|
+
data.tar.gz: 81467077618908f8e4ce9289072a7cb760f61fe9e40ca5992d39a9e7bba406d1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 680143be9e6ea67deec9ab82c3cac7ab412c177a65519852e88ab8873777df0797cd3cf05f84a8cddea15599d25f0fae8428df9679b539246c7002175ea127f6
|
7
|
+
data.tar.gz: c3b7362ef0c83103cf2ab9d876335ca0e9501194d3afca4eabf92db1f0e60b74c0643e880929ed3a7eb2faa40be49f12012d6dc17603ea382171a2a588da5398
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,34 @@ scheme are considered to be bugs.
|
|
6
6
|
|
7
7
|
[semver]: http://semver.org/spec/v2.0.0.html
|
8
8
|
|
9
|
+
## [4.0.0] - 2019-10-30
|
10
|
+
|
11
|
+
[4.0.0]: https://github.com/intridea/hashie/compare/v3.6.0...v4.0.0
|
12
|
+
|
13
|
+
### Added
|
14
|
+
|
15
|
+
* [#323](https://github.com/intridea/hashie/pull/323): Added `Hashie::Extensions::Mash::DefineAccessors` - [@marshall-lee](https://github.com/marshall-lee).
|
16
|
+
* [#474](https://github.com/intridea/hashie/pull/474): Expose `YAML#safe_load` options in `Mash#load` - [@riouruma](https://github.com/riouruma), [@dblock](https://github.com/dblock).
|
17
|
+
* [#478](https://github.com/intridea/hashie/pull/478): Added optional array parameter to `Hashie::Mash.disable_warnings` - [@bobbymcwho](https://github.com/bobbymcwho).
|
18
|
+
* [#481](https://github.com/intridea/hashie/pull/481): Ruby 2.6 - Support `Hash#merge` and `#merge!` called with multiple Hashes/Mashes - [@bobbymcwho](https://github.com/bobbymcwho).
|
19
|
+
* [#488](https://github.com/intridea/hashie/pull/488): Added ability to create an anonymous `Hashie::Mash` subclass with key conflict errors silenced using `Hashie::Mash.quiet.new` - [@bobbymcwho](https://github.com/bobbymcwho).
|
20
|
+
|
21
|
+
### Changed
|
22
|
+
|
23
|
+
* [#481](https://github.com/intridea/hashie/pull/481): Implement non-destructive standard Hash methods - [@bobbymcwho](https://github.com/bobbymcwho).
|
24
|
+
|
25
|
+
### Fixed
|
26
|
+
|
27
|
+
* [#459](https://github.com/intridea/hashie/pull/459): Fixed a regression in `Mash.load` that disallowed aliases - [@arekt](https://github.com/arekt) and [@michaelherold](https://github.com/michaelherold).
|
28
|
+
* [#465](https://github.com/intridea/hashie/pull/465): Fixed `deep_update` to call any readers when a key exists - [@laertispappas](https://github.com/laertispappas).
|
29
|
+
* [#479](https://github.com/intridea/hashie/pull/479): Fixed an issue with `Hash#except` not returning a `Mash` in Rails 6 - [@bobbymcwho](https://github.com/bobbymcwho).
|
30
|
+
* [#489](https://github.com/intridea/hashie/pull/489): Updated the documentation to exlain the behavior of `Mash` and keyword arguments - [@Bhacaz](https://github.com/Bhacaz).
|
31
|
+
|
32
|
+
### Miscellaneous
|
33
|
+
|
34
|
+
* [#465](https://github.com/intridea/hashie/pull/465): Clean up our RuboCop configuration and fix the outstanding line length violations. This involved some minor refactoring on `Hashie::Extensions::Coercion`, `Hashie::Extensions::Dash::IndifferentAccess`, `Hashie::Extensions::DeepLocate`, `Hashie::Extensions::Mash::SafeAssignment`, and `Hashie::Hash`, but none that were detectable via the test suite - [@michaelherold](https://github.com/michaelherold).
|
35
|
+
* [#482](https://github.com/intridea/hashie/pull/482): Update Travis configs to make jruby builds run on trusty dist. - [@BobbyMcWho](https://github.com/BobbyMcWho).
|
36
|
+
|
9
37
|
## [3.6.0] - 2018-08-13
|
10
38
|
|
11
39
|
[3.6.0]: https://github.com/intridea/hashie/compare/v3.5.7...v3.6.0
|
data/README.md
CHANGED
@@ -18,7 +18,7 @@ $ gem install hashie
|
|
18
18
|
|
19
19
|
## Upgrading
|
20
20
|
|
21
|
-
You're reading the documentation for the stable release of Hashie,
|
21
|
+
You're reading the documentation for the stable release of Hashie, 4.0.0. Please read [UPGRADING](UPGRADING.md) when upgrading from a previous version.
|
22
22
|
|
23
23
|
## Hash Extensions
|
24
24
|
|
@@ -190,7 +190,7 @@ end
|
|
190
190
|
|
191
191
|
### KeyConversion
|
192
192
|
|
193
|
-
The KeyConversion extension gives you the convenience methods of `symbolize_keys` and `stringify_keys` along with their bang counterparts. You can also include just stringify or just symbolize with `Hashie::Extensions::StringifyKeys` or `Hashie::Extensions::SymbolizeKeys
|
193
|
+
The KeyConversion extension gives you the convenience methods of `symbolize_keys` and `stringify_keys` along with their bang counterparts. You can also include just stringify or just symbolize with `Hashie::Extensions::StringifyKeys` or [`Hashie::Extensions::SymbolizeKeys`](#mash-extension-symbolizekeys).
|
194
194
|
|
195
195
|
Hashie also has a utility method for converting keys on a Hash without a mixin:
|
196
196
|
|
@@ -316,8 +316,8 @@ p.email # => NoMethodError
|
|
316
316
|
|
317
317
|
### DeepMerge
|
318
318
|
|
319
|
-
This extension
|
320
|
-
system
|
319
|
+
This extension allows you to easily include a recursive merging
|
320
|
+
system into any Hash descendant:
|
321
321
|
|
322
322
|
```ruby
|
323
323
|
class MyHash < Hash
|
@@ -515,6 +515,55 @@ class Response < Hashie::Mash
|
|
515
515
|
end
|
516
516
|
```
|
517
517
|
|
518
|
+
The default is to disable logging for all methods that conflict. If you would like to only disable the logging for specific methods, you can include an array of method keys:
|
519
|
+
|
520
|
+
```ruby
|
521
|
+
class Response < Hashie::Mash
|
522
|
+
disable_warnings :zip, :zap
|
523
|
+
end
|
524
|
+
```
|
525
|
+
|
526
|
+
This behavior is cumulative. The examples above and below behave identically.
|
527
|
+
|
528
|
+
```ruby
|
529
|
+
class Response < Hashie::Mash
|
530
|
+
disable_warnings :zip
|
531
|
+
disable_warnings :zap
|
532
|
+
end
|
533
|
+
```
|
534
|
+
|
535
|
+
Disable warnings will honor the last `disable_warnings` call. Calling without parameters will override the ignored methods list, and calling with parameters will create a new ignored methods list. This includes child classes that inherit from a class that disables warnings.
|
536
|
+
|
537
|
+
```ruby
|
538
|
+
class Message < Hashie::Mash
|
539
|
+
disable_warnings :zip, :zap
|
540
|
+
disable_warnings
|
541
|
+
end
|
542
|
+
|
543
|
+
# No errors will be logged
|
544
|
+
Message.new(merge: 'true', compact: true)
|
545
|
+
```
|
546
|
+
|
547
|
+
```ruby
|
548
|
+
class Message < Hashie::Mash
|
549
|
+
disable_warnings
|
550
|
+
end
|
551
|
+
|
552
|
+
class Response < Message
|
553
|
+
disable_warnings :zip, :zap
|
554
|
+
end
|
555
|
+
|
556
|
+
# 2 errors will be logged
|
557
|
+
Response.new(merge: 'true', compact: true, zip: '90210', zap: 'electric')
|
558
|
+
```
|
559
|
+
|
560
|
+
If you would like to create an anonymous subclass of a Hashie::Mash with key conflict warnings disabled:
|
561
|
+
|
562
|
+
```ruby
|
563
|
+
Hashie::Mash.quiet.new(zip: '90210', compact: true) # no errors logged
|
564
|
+
Hashie::Mash.quiet(:zip).new(zip: '90210', compact: true) # error logged for compact
|
565
|
+
```
|
566
|
+
|
518
567
|
### How does the wrapping of Mash sub-Hashes work?
|
519
568
|
|
520
569
|
Mash duplicates any sub-Hashes that you add to it and wraps them in a Mash. This allows for infinite chaining of nested Hashes within a Mash without modifying the object(s) that are passed into the Mash. When you subclass Mash, the subclass wraps any sub-Hashes in its own class. This preserves any extensions that you mixed into the Mash subclass and allows them to work within the sub-Hashes, in addition to the main containing Mash.
|
@@ -566,7 +615,7 @@ Twitter.extend mash.to_module # NOTE: if you want another name than settings, ca
|
|
566
615
|
Twitter.settings.api_key # => 'abcd'
|
567
616
|
```
|
568
617
|
|
569
|
-
You can use another parser (by default: YamlErbParser):
|
618
|
+
You can use another parser (by default: [YamlErbParser](lib/hashie/extensions/parsers/yaml_erb_parser.rb)):
|
570
619
|
|
571
620
|
```
|
572
621
|
#/etc/data/user.csv
|
@@ -582,6 +631,14 @@ mash = Mash.load('data/user.csv', parser: MyCustomCsvParser)
|
|
582
631
|
mash[1] #=> { name: 'John', lastname: 'Doe' }
|
583
632
|
```
|
584
633
|
|
634
|
+
The `Mash#load` method calls `YAML.safe_load(path, [], [], true)`.
|
635
|
+
|
636
|
+
Specify `permitted_symbols`, `permitted_classes` and `aliases` options as needed.
|
637
|
+
|
638
|
+
```ruby
|
639
|
+
Mash.load('data/user.csv', permitted_classes: [Symbol], permitted_symbols: [], aliases: false)
|
640
|
+
```
|
641
|
+
|
585
642
|
### Mash Extension: KeepOriginalKeys
|
586
643
|
|
587
644
|
This extension can be mixed into a Mash to keep the form of any keys passed directly into the Mash. By default, Mash converts keys to strings to give indifferent access. This extension still allows indifferent access, but keeps the form of the keys to eliminate confusion when you're not expecting the keys to change.
|
@@ -617,9 +674,9 @@ safe_mash.zip = 'Test' # => ArgumentError
|
|
617
674
|
safe_mash[:zip] = 'test' # => still ArgumentError
|
618
675
|
```
|
619
676
|
|
620
|
-
### Mash Extension
|
677
|
+
### Mash Extension: SymbolizeKeys
|
621
678
|
|
622
|
-
This extension can be mixed into a Mash to change the default behavior of converting keys to strings. After mixing this extension into a Mash, the Mash will convert all keys to symbols.
|
679
|
+
This extension can be mixed into a Mash to change the default behavior of converting keys to strings. After mixing this extension into a Mash, the Mash will convert all keys to symbols. It can be useful to use with keywords argument, which required symbol keys.
|
623
680
|
|
624
681
|
```ruby
|
625
682
|
class SymbolizedMash < ::Hashie::Mash
|
@@ -630,6 +687,12 @@ symbol_mash = SymbolizedMash.new
|
|
630
687
|
symbol_mash['test'] = 'value'
|
631
688
|
symbol_mash.test #=> 'value'
|
632
689
|
symbol_mash.to_h #=> {test: 'value'}
|
690
|
+
|
691
|
+
def example(test:)
|
692
|
+
puts test
|
693
|
+
end
|
694
|
+
|
695
|
+
example(symbol_mash) #=> value
|
633
696
|
```
|
634
697
|
|
635
698
|
There is a major benefit and coupled with a major trade-off to this decision (at least on older Rubies). As a benefit, by using symbols as keys, you will be able to use the implicit conversion of a Mash via the `#to_hash` method to destructure (or splat) the contents of a Mash out to a block. This can be handy for doing iterations through the Mash's keys and values, as follows:
|
@@ -644,6 +707,31 @@ end
|
|
644
707
|
|
645
708
|
However, on Rubies less than 2.0, this means that every key you send to the Mash will generate a symbol. Since symbols are not garbage-collected on older versions of Ruby, this can cause a slow memory leak when using a symbolized Mash with data generated from user input.
|
646
709
|
|
710
|
+
### Mash Extension: DefineAccessors
|
711
|
+
|
712
|
+
This extension can be mixed into a Mash so it makes it behave like `OpenStruct`. It reduces the overhead of `method_missing?` magic by lazily defining field accessors when they're requested.
|
713
|
+
|
714
|
+
```ruby
|
715
|
+
class MyHash < ::Hashie::Mash
|
716
|
+
include Hashie::Extensions::Mash::DefineAccessors
|
717
|
+
end
|
718
|
+
|
719
|
+
mash = MyHash.new
|
720
|
+
MyHash.method_defined?(:foo=) #=> false
|
721
|
+
mash.foo = 123
|
722
|
+
MyHash.method_defined?(:foo=) #=> true
|
723
|
+
|
724
|
+
MyHash.method_defined?(:foo) #=> false
|
725
|
+
mash.foo #=> 123
|
726
|
+
MyHash.method_defined?(:foo) #=> true
|
727
|
+
```
|
728
|
+
|
729
|
+
You can also extend the existing mash without defining a class:
|
730
|
+
|
731
|
+
```ruby
|
732
|
+
mash = ::Hashie::Mash.new.with_accessors!
|
733
|
+
```
|
734
|
+
|
647
735
|
## Dash
|
648
736
|
|
649
737
|
Dash is an extended Hash that has a discrete set of defined properties and only those properties may be set on the hash. Additionally, you can set defaults for each property. You can also flag a property as required. Required properties will raise an exception if unset. Another option is message for required properties, which allow you to add custom messages for required property.
|
data/UPGRADING.md
CHANGED
@@ -1,6 +1,84 @@
|
|
1
1
|
Upgrading Hashie
|
2
2
|
================
|
3
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
|
+
|
4
82
|
### Upgrading to 3.5.2
|
5
83
|
|
6
84
|
#### Disable logging in Mash subclasses
|
@@ -165,5 +243,3 @@ instance.to_hash # => { :first => 'First', "last" => 'Last' }
|
|
165
243
|
The behavior with `symbolize_keys` and `stringify_keys` is unchanged.
|
166
244
|
|
167
245
|
See [#152](https://github.com/intridea/hashie/pull/152) for more information.
|
168
|
-
|
169
|
-
|
data/hashie.gemspec
CHANGED
@@ -11,7 +11,8 @@ Gem::Specification.new do |gem|
|
|
11
11
|
gem.license = 'MIT'
|
12
12
|
|
13
13
|
gem.require_paths = ['lib']
|
14
|
-
gem.files
|
14
|
+
gem.files = %w[.yardopts CHANGELOG.md CONTRIBUTING.md LICENSE README.md UPGRADING.md]
|
15
|
+
gem.files += %w[Rakefile hashie.gemspec]
|
15
16
|
gem.files += Dir['lib/**/*.rb']
|
16
17
|
gem.files += Dir['spec/**/*.rb']
|
17
18
|
gem.test_files = Dir['spec/**/*.rb']
|
data/lib/hashie.rb
CHANGED
@@ -12,26 +12,26 @@ module Hashie
|
|
12
12
|
autoload :Utils, 'hashie/utils'
|
13
13
|
|
14
14
|
module Extensions
|
15
|
-
autoload :Coercion,
|
16
|
-
autoload :DeepMerge,
|
17
|
-
autoload :IgnoreUndeclared,
|
18
|
-
autoload :IndifferentAccess,
|
19
|
-
autoload :MergeInitializer,
|
20
|
-
autoload :MethodAccess,
|
21
|
-
autoload :MethodQuery,
|
22
|
-
autoload :MethodReader,
|
23
|
-
autoload :MethodWriter,
|
24
|
-
autoload :StringifyKeys,
|
25
|
-
autoload :SymbolizeKeys,
|
26
|
-
autoload :DeepFetch,
|
27
|
-
autoload :DeepFind,
|
28
|
-
autoload :DeepLocate,
|
29
|
-
autoload :PrettyInspect,
|
30
|
-
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'
|
31
31
|
autoload :MethodAccessWithOverride, 'hashie/extensions/method_access'
|
32
|
-
autoload :StrictKeyAccess,
|
33
|
-
autoload :RubyVersion,
|
34
|
-
autoload :RubyVersionCheck,
|
32
|
+
autoload :StrictKeyAccess, 'hashie/extensions/strict_key_access'
|
33
|
+
autoload :RubyVersion, 'hashie/extensions/ruby_version'
|
34
|
+
autoload :RubyVersionCheck, 'hashie/extensions/ruby_version_check'
|
35
35
|
|
36
36
|
module Parsers
|
37
37
|
autoload :YamlErbParser, 'hashie/extensions/parsers/yaml_erb_parser'
|
@@ -47,6 +47,7 @@ module Hashie
|
|
47
47
|
autoload :KeepOriginalKeys, 'hashie/extensions/mash/keep_original_keys'
|
48
48
|
autoload :SafeAssignment, 'hashie/extensions/mash/safe_assignment'
|
49
49
|
autoload :SymbolizeKeys, 'hashie/extensions/mash/symbolize_keys'
|
50
|
+
autoload :DefineAccessors, 'hashie/extensions/mash/define_accessors'
|
50
51
|
end
|
51
52
|
|
52
53
|
module Array
|
data/lib/hashie/dash.rb
CHANGED
@@ -219,7 +219,8 @@ module Hashie
|
|
219
219
|
end
|
220
220
|
|
221
221
|
def fail_property_required_error!(property)
|
222
|
-
raise ArgumentError,
|
222
|
+
raise ArgumentError,
|
223
|
+
"The property '#{property}' #{self.class.required_properties[property][:message]}"
|
223
224
|
end
|
224
225
|
|
225
226
|
def fail_no_property_error!(property)
|
@@ -1,5 +1,9 @@
|
|
1
1
|
module Hashie
|
2
|
-
class CoercionError < StandardError
|
2
|
+
class CoercionError < StandardError
|
3
|
+
def initialize(key, value, into, message)
|
4
|
+
super("Cannot coerce property #{key.inspect} from #{value.class} to #{into}: #{message}")
|
5
|
+
end
|
6
|
+
end
|
3
7
|
|
4
8
|
module Extensions
|
5
9
|
module Coercion
|
@@ -12,20 +16,22 @@ module Hashie
|
|
12
16
|
Symbol => :to_sym
|
13
17
|
}.freeze
|
14
18
|
|
15
|
-
ABSTRACT_CORE_TYPES =
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
19
|
+
ABSTRACT_CORE_TYPES =
|
20
|
+
if RubyVersion.new(RUBY_VERSION) >= RubyVersion.new('2.4.0')
|
21
|
+
{ Numeric => [Integer, Float, Complex, Rational] }
|
22
|
+
else
|
23
|
+
{
|
24
|
+
Integer => [Fixnum, Bignum],
|
25
|
+
Numeric => [Fixnum, Bignum, Float, Complex, Rational]
|
26
|
+
}
|
27
|
+
end
|
23
28
|
|
24
29
|
def self.included(base)
|
25
30
|
base.send :include, InstanceMethods
|
26
|
-
base.extend ClassMethods
|
27
|
-
|
28
|
-
|
31
|
+
base.extend ClassMethods
|
32
|
+
unless base.method_defined?(:set_value_without_coercion)
|
33
|
+
base.send :alias_method, :set_value_without_coercion, :[]=
|
34
|
+
end
|
29
35
|
base.send :alias_method, :[]=, :set_value_with_coercion
|
30
36
|
end
|
31
37
|
|
@@ -37,7 +43,7 @@ module Hashie
|
|
37
43
|
begin
|
38
44
|
value = self.class.fetch_coercion(into).call(value)
|
39
45
|
rescue NoMethodError, TypeError => e
|
40
|
-
raise CoercionError,
|
46
|
+
raise CoercionError.new(key, value, into, e.message)
|
41
47
|
end
|
42
48
|
end
|
43
49
|
|
@@ -97,7 +103,8 @@ module Hashie
|
|
97
103
|
#
|
98
104
|
# @param [Class] from the type you would like coerced.
|
99
105
|
# @param [Class] into the class into which you would like the value coerced.
|
100
|
-
# @option options [Boolean] :strict (true) whether use exact source class
|
106
|
+
# @option options [Boolean] :strict (true) whether use exact source class
|
107
|
+
# only or include ancestors
|
101
108
|
#
|
102
109
|
# @example Coerce all hashes into this special type of hash
|
103
110
|
# class SpecialHash < Hash
|
@@ -159,10 +166,10 @@ module Hashie
|
|
159
166
|
|
160
167
|
def build_coercion(type)
|
161
168
|
if type.is_a? Enumerable
|
162
|
-
if type.class
|
169
|
+
if type.class == ::Hash
|
163
170
|
type, key_type, value_type = type.class, *type.first
|
164
171
|
build_hash_coercion(type, key_type, value_type)
|
165
|
-
else
|
172
|
+
else
|
166
173
|
value_type = type.first
|
167
174
|
type = type.class
|
168
175
|
build_container_coercion(type, value_type)
|