hashie 4.1.0 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 97b60a3200a49e6f1e56b3d29978c381b8087bb5eeda134ae6ab2a3924f49001
4
- data.tar.gz: 35a74ae35652f8c0f8673995edaae1b4e15850bdcd0141545bd5cee4ada19f40
3
+ metadata.gz: 7e486322b7af0b141230bee75284517915509dfb717d337ef302456c304674d2
4
+ data.tar.gz: 7f411b4145d887f744fd82670213a8a9e46aaf4cf5b21a54cd1a3bf0ae856b4e
5
5
  SHA512:
6
- metadata.gz: 428fec8afebba7c475b5e71d56f749dc0477dc1bb15143fa21bfc8b45087ffccd4012dd745b5bbbde690939d1f44f0109383a504f9c44e7f4631dead1263ea44
7
- data.tar.gz: 9ef563e80a10babdc0719b4b88004ba3b571441191335baf45d9292478c585cc919d598bfc32c4d246448ce4777f64030de2f968e53388e4166c8562e66d5860
6
+ metadata.gz: fd45a860107493799300af41d201ed7c510b34a69d39134ddabb0118bb146e92febc8b16a863dd7029298c9a772ab64ac9ccc1841f57eb6889d4f9a3c38508ad
7
+ data.tar.gz: 44144002988d160b001e00e3a90054a9440e3d705f30f68037ed9dab7a271fa5f15c5a458e3c33a8146830a09945c374e6d449931bf088de7eed38e2b1acc82b
data/CHANGELOG.md CHANGED
@@ -1,10 +1,43 @@
1
- # Change Log
1
+ # Changelog
2
2
 
3
- All notable changes to this project will be documented in this file. This
4
- project adheres to [Semantic Versioning 2.0.0][semver]. Any violations of this
5
- scheme are considered to be bugs.
3
+ All notable changes to this project will be documented in this file.
6
4
 
7
- [semver]: http://semver.org/spec/v2.0.0.html
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+ Any violations of this scheme are considered to be bugs.
8
+
9
+ ## [5.0.0] - 2021-11-08
10
+
11
+ [5.0.0]: https://github.com/hashie/hashie/compare/v4.1.0...v5.0.0
12
+
13
+ ### Added
14
+
15
+ * [#523](https://github.com/hashie/hashie/pull/523): Added TOC, ensure a keep-a-changelog formatted CHANGELOG - [@dblock](https://github.com/dblock).
16
+ * [#522](https://github.com/hashie/hashie/pull/522): Added eierlegende Wollmilchsau mascot graphic - [@carolineartz](https://github.com/carolineartz).
17
+ * [#530](https://github.com/hashie/hashie/pull/530): Added Hashie::Extensions::Dash::PredefinedValues - [@caalberts](https://github.com/caalberts).
18
+ * [#536](https://github.com/hashie/hashie/pull/536): Added exporting a normal Hash from an indifferent one through the `#to_hash` method - [@michaelherold](https://github.com/michaelherold).
19
+ * [#539](https://github.com/hashie/hashie/pull/539): Run 2.7 tests once - [@anakinj](https://github.com/anakinj).
20
+
21
+ ### Changed
22
+
23
+ * [#521](https://github.com/hashie/hashie/pull/499): Do not convert keys that cannot be represented as symbols to `String` in `Mash` initialization - [@carolineartz](https://github.com/carolineartz).
24
+ * [#524](https://github.com/hashie/hashie/pull/524): Test with Ruby 2.7 - [@aried3r](https://github.com/aried3r).
25
+ * [#525](https://github.com/hashie/hashie/pull/525): Use `indifferent_writer` in `IndifferentAccess#convert!` - [@yogeshjain999](https://github.com/yogeshjain999).
26
+ * [#527](https://github.com/hashie/hashie/pull/527): Updated Copyright to (c) 2009-2020 Intridea, Inc., and Contributors - [@dblock](https://github.com/dblock).
27
+ * [#555](https://github.com/hashie/hashie/pull/555): Test with Ruby 3.0 - [@dblock](https://github.com/dblock).
28
+
29
+ ### Removed
30
+
31
+ * [#538](https://github.com/hashie/hashie/pull/538): Dropped testing for JRuby 9.0, though not support - [@michaelherold](https://github.com/michaelherold).
32
+
33
+ ### Fixed
34
+
35
+ * [#516](https://github.com/hashie/hashie/issues/516): Fixed `NoMethodError` raised when including `Hashie::Extensions::Mash::SymbolizeKeys` and `Hashie::Extensions::SymbolizeKeys` in mashes/hashes with non string or symbol keys - [@carolineartz](https://github.com/carolineartz).
36
+ * [#531](https://github.com/hashie/hashie/pull/531): Fixed [slice doesn't work using symbols](https://github.com/hashie/hashie/issues/529) using hash with `IndifferentAccess` extension - [@gnomex](https://github.com/gnomex).
37
+ * [#533](https://github.com/hashie/hashie/pull/533): Fixed `NoMethodError: undefined method 'to_json'` at `hashie/dash_spec` - [@gnomex](https://github.com/gnomex).
38
+ * [#535](https://github.com/hashie/hashie/pull/535): Restored the exporting of all properties as part of `Dash#to_h` and `Dash#to_hash` - [@michaelherold](https://github.com/michaelherold).
39
+ * [#537](https://github.com/hashie/hashie/pull/537): Fixed inconsistencies with handling defaults in `Dash` with and without `IgnoreUnclared` mixed in - [@michaelherold](https://github.com/michaelherold).
40
+ * [#547](https://github.com/hashie/hashie/pull/547): Fixed issue where a source hash key can be used in translating multiple properties - [@danwa5](https://github.com/danwa5).
8
41
 
9
42
  ## [4.1.0] - 2020-02-01
10
43
 
@@ -12,8 +45,13 @@ scheme are considered to be bugs.
12
45
 
13
46
  ### Added
14
47
 
48
+ * [#545](https://github.com/hashie/hashie/pull/545): Add `Hashie::Mash#except` and `Hashie::Extensions::IndifferentAccess#except` when running under Ruby 3 to match newly added Ruby stdlib method - [@jackjennings](https://github.com/jackjennings).
15
49
  * [#499](https://github.com/hashie/hashie/pull/499): Add `Hashie::Extensions::Mash::PermissiveRespondTo` to make specific subclasses of Mash fully respond to messages for use with `SimpleDelegator` - [@michaelherold](https://github.com/michaelherold).
16
50
 
51
+ ### Changed
52
+
53
+ * [#498](https://github.com/hashie/hashie/pull/498): Exclude tests from the gem release to reduce installation size and improve installation speed - [@michaelherold](https://github.com/michaelherold).
54
+
17
55
  ### Fixed
18
56
 
19
57
  * [#467](https://github.com/intridea/hashie/pull/467): Fixed `DeepMerge#deep_merge` mutating nested values within the receiver - [@michaelherold](https://github.com/michaelherold).
@@ -27,11 +65,6 @@ scheme are considered to be bugs.
27
65
  * [#512](https://github.com/hashie/hashie/pull/512): Suppress an integer unification warning for using Ruby 2.4.0+ - [@koic](https://github.com/koic).
28
66
  * [#513](https://github.com/hashie/hashie/pull/513): Suppress a Ruby's warning when using Ruby 2.6.0+ - [@koic](https://github.com/koic).
29
67
 
30
- ### Miscellaneous
31
-
32
- * [#981](https://github.com/hashie/hashie/pull/981): Exclude tests from the gem release to reduce installation size and improve installation speed - [@michaelherold](https://github.com/michaelherold).
33
- * Your contribution here.
34
-
35
68
  ## [4.0.0] - 2019-10-30
36
69
 
37
70
  [4.0.0]: https://github.com/hashie/hashie/compare/v3.6.0...v4.0.0
@@ -47,6 +80,7 @@ scheme are considered to be bugs.
47
80
  ### Changed
48
81
 
49
82
  * [#481](https://github.com/hashie/hashie/pull/481): Implement non-destructive standard Hash methods - [@bobbymcwho](https://github.com/bobbymcwho).
83
+ * [#482](https://github.com/hashie/hashie/pull/482): Update Travis configs to make jruby builds run on trusty dist - [@BobbyMcWho](https://github.com/BobbyMcWho).
50
84
 
51
85
  ### Fixed
52
86
 
@@ -54,11 +88,7 @@ scheme are considered to be bugs.
54
88
  * [#465](https://github.com/hashie/hashie/pull/465): Fixed `deep_update` to call any readers when a key exists - [@laertispappas](https://github.com/laertispappas).
55
89
  * [#479](https://github.com/hashie/hashie/pull/479): Fixed an issue with `Hash#except` not returning a `Mash` in Rails 6 - [@bobbymcwho](https://github.com/bobbymcwho).
56
90
  * [#489](https://github.com/hashie/hashie/pull/489): Updated the documentation to exlain the behavior of `Mash` and keyword arguments - [@Bhacaz](https://github.com/Bhacaz).
57
-
58
- ### Miscellaneous
59
-
60
91
  * [#465](https://github.com/hashie/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).
61
- * [#482](https://github.com/hashie/hashie/pull/482): Update Travis configs to make jruby builds run on trusty dist. - [@BobbyMcWho](https://github.com/BobbyMcWho).
62
92
 
63
93
  ## [3.6.0] - 2018-08-13
64
94
 
@@ -67,6 +97,12 @@ scheme are considered to be bugs.
67
97
  ### Added
68
98
 
69
99
  * [#455](https://github.com/hashie/hashie/pull/455): Allow overriding methods when passing in a hash - [@lnestor](https://github.com/lnestor).
100
+ * [#434](https://github.com/hashie/hashie/pull/434): Add documentation around Mash sub-Hashes - [@michaelherold](https://github.com/michaelherold).
101
+ * [#439](https://github.com/hashie/hashie/pull/439): Add an integration spec for Elasticsearch - [@michaelherold](https://github.com/michaelherold).
102
+
103
+ ### Changed
104
+
105
+ * [#433](https://github.com/hashie/hashie/pull/433): Update Rubocop to the most recent version - [@michaelherold](https://github.com/michaelherold).
70
106
 
71
107
  ### Fixed
72
108
 
@@ -76,21 +112,15 @@ scheme are considered to be bugs.
76
112
  * [#438](https://github.com/hashie/hashie/pull/438): Fix: `NameError (uninitialized constant Hashie::Extensions::Parsers::YamlErbParser::Pathname)` in `Hashie::Mash.load` - [@onk](https://github.com/onk).
77
113
  * [#457](https://github.com/hashie/hashie/pull/457): Fix `Trash` to allow it to copy properties from other properties - [@michaelherold](https://github.com/michaelherold).
78
114
 
79
- ### Miscellaneous
80
-
81
- * [#433](https://github.com/hashie/hashie/pull/433): Update Rubocop to the most recent version - [@michaelherold](https://github.com/michaelherold).
82
- * [#434](https://github.com/hashie/hashie/pull/434): Add documentation around Mash sub-Hashes - [@michaelherold](https://github.com/michaelherold).
83
- * [#439](https://github.com/hashie/hashie/pull/439): Add an integration spec for Elasticsearch - [@michaelherold](https://github.com/michaelherold).
84
-
85
115
  ## [3.5.7] - 2017-12-19
86
116
 
87
117
  [3.5.7]: https://github.com/hashie/hashie/compare/v3.5.6...v3.5.7
88
118
 
89
119
  ### Fixed
90
120
 
91
- [#430](https://github.com/hashie/hashie/pull/430): Fix Hashie::Rash randomly losing items - [@Antti](https://github.com/Antti)
121
+ * [#430](https://github.com/hashie/hashie/pull/430): Fix Hashie::Rash randomly losing items - [@Antti](https://github.com/Antti).
92
122
 
93
- ### Miscellaneous
123
+ ### Changed
94
124
 
95
125
  * [#425](https://github.com/hashie/hashie/pull/425): Update rubies in CI - [@kachick](https://github.com/kachick).
96
126
 
@@ -98,7 +128,7 @@ scheme are considered to be bugs.
98
128
 
99
129
  [3.5.6]: https://github.com/hashie/hashie/compare/v3.5.5...v3.5.6
100
130
 
101
- ### Miscellaneous
131
+ ### Fixed
102
132
 
103
133
  * [#416](https://github.com/hashie/hashie/pull/416): Fix `warning: instance variable @disable_warnings not initialized` - [@axfcampos](https://github.com/axfcampos).
104
134
 
@@ -145,16 +175,13 @@ scheme are considered to be bugs.
145
175
 
146
176
  * [#395](https://github.com/hashie/hashie/pull/395): Add the ability to disable warnings in Mash subclasses - [@michaelherold](https://github.com/michaelherold).
147
177
  * [#400](https://github.com/hashie/hashie/pull/400): Fix Hashie.logger load and set the Hashie logger to the Rails logger in a Rails environment - [@michaelherold](https://github.com/michaelherold).
178
+ * [#397](https://github.com/hashie/hashie/pull/397): Add the integration specs harness into the main test tasks - [@michaelherold](https://github.com/michaelherold).
148
179
 
149
180
  ### Fixed
150
181
 
151
182
  * [#396](https://github.com/hashie/hashie/pull/396): Fix for specs in #381: Incorrect use of shared context meant example was not being run - [@biinari](https://github.com/biinari).
152
183
  * [#399](https://github.com/hashie/hashie/pull/399): Fix passing Pathname object to Hashie::Mesh.load() - [@albb0920](https://github.com/albb0920).
153
184
 
154
- ### Miscellanous
155
-
156
- * [#397](https://github.com/hashie/hashie/pull/397): Add the integration specs harness into the main test tasks - [@michaelherold](https://github.com/michaelherold).
157
-
158
185
  ## [3.5.1] - 2017-01-31
159
186
 
160
187
  * [#392](https://github.com/hashie/hashie/pull/392): Fix for #391: Require all dependencies of Hashie::Mash - [@dblock](https://github.com/dblock).
@@ -183,10 +210,7 @@ scheme are considered to be bugs.
183
210
  * [#377](https://github.com/hashie/hashie/pull/377): Dont use Rubygems to check ruby version - [@sazor](https://github.com/sazor).
184
211
  * [#378](https://github.com/hashie/hashie/pull/378): Deep find all searches inside all nested hashes - [@sazor](https://github.com/sazor).
185
212
  * [#380](https://github.com/hashie/hashie/pull/380): Evaluate procs default values of Dash in object initialization - [@sazor](https://github.com/sazor).
186
-
187
- ### Miscellanous
188
-
189
- * [#387](https://github.com/hashie/hashie/pull/387): Fix builds failing due to Rake 11 having a breaking change - [@michaelherold](https://github.com/michaelherold).
213
+ * [#387](https://github.com/hashie/hashie/pull/387): Fixed builds failing due to Rake 11 having a breaking change - [@michaelherold](https://github.com/michaelherold).
190
214
 
191
215
  ## [3.4.6] - 2016-09-16
192
216
 
@@ -203,6 +227,7 @@ scheme are considered to be bugs.
203
227
  ### Added
204
228
 
205
229
  * [#337](https://github.com/hashie/hashie/pull/337), [#331](https://github.com/hashie/hashie/issues/331): `Hashie::Mash#load` accepts a `Pathname` object - [@gipcompany](https://github.com/gipcompany).
230
+ * [#366](https://github.com/hashie/hashie/pull/366): Added Danger, PR linter - [@dblock](https://github.com/dblock).
206
231
 
207
232
  ### Deprecated
208
233
 
@@ -213,10 +238,6 @@ scheme are considered to be bugs.
213
238
  * [#358](https://github.com/hashie/hashie/pull/358): Fixed support for Array#dig - [@modosc](https://github.com/modosc).
214
239
  * [#365](https://github.com/hashie/hashie/pull/365): Ensured ActiveSupport::HashWithIndifferentAccess is defined before use in #deep_locate - [@mikejarema](https://github.com/mikejarema).
215
240
 
216
- ### Miscellanous
217
-
218
- * [#366](https://github.com/hashie/hashie/pull/366): Added Danger, PR linter - [@dblock](https://github.com/dblock).
219
-
220
241
  ## [3.4.4] - 2016-04-29
221
242
 
222
243
  [3.4.4]: https://github.com/hashie/hashie/compare/v3.4.3...v3.4.4
@@ -248,7 +269,7 @@ scheme are considered to be bugs.
248
269
  * [#304](https://github.com/hashie/hashie/pull/304): Ensured compatibility of `Hash` extensions with singleton objects - [@regexident](https://github.com/regexident).
249
270
  * [#310](https://github.com/hashie/hashie/pull/310): Fixed `Hashie::Extensions::SafeAssignment` bug with private methods - [@marshall-lee](https://github.com/marshall-lee).
250
271
 
251
- ### Miscellaneous
272
+ ### Changed
252
273
 
253
274
  * [#313](https://github.com/hashie/hashie/pull/313): Restrict pending spec to only Ruby versions 2.2.0-2.2.2 - [@pboling](https://github.com/pboling).
254
275
  * [#315](https://github.com/hashie/hashie/pull/315): Default `bin/` scripts: `console` and `setup` - [@pboling](https://github.com/pboling).
@@ -383,8 +404,6 @@ scheme are considered to be bugs.
383
404
 
384
405
  [3.0.0]: https://github.com/hashie/hashie/compare/v2.1.2...v3.0.0
385
406
 
386
- Note: This version introduces several backward incompatible API changes. See [UPGRADING](UPGRADING.md) for details.
387
-
388
407
  ### Added
389
408
 
390
409
  * [#149](https://github.com/hashie/hashie/issues/149): Allow IgnoreUndeclared and DeepMerge to be used with undeclared properties - [@jhaesus](https://github.com/jhaesus).
@@ -429,6 +448,7 @@ Note: This version introduces several backward incompatible API changes. See [UP
429
448
  ### Changed
430
449
 
431
450
  * [#89](https://github.com/hashie/hashie/issues/89): Do not respond to every method with suffix in Hashie::Mash, fixes Rails strong_parameters - [@Maxim-Filimonov](https://github.com/Maxim-Filimonov).
451
+ * Ruby style now enforced with Rubocop - [@dblock](https://github.com/dblock).
432
452
 
433
453
  ### Removed
434
454
 
@@ -450,10 +470,6 @@ Note: This version introduces several backward incompatible API changes. See [UP
450
470
  * [#130](https://github.com/hashie/hashie/pull/130): IndifferentAccess now works without MergeInitializer - [@npj](https://github.com/npj).
451
471
  * [#133](https://github.com/hashie/hashie/pull/133): Fixed Hash##to_hash with symbolize_keys - [@mhuggins](https://github.com/mhuggins).
452
472
 
453
- ### Miscellaneous
454
-
455
- * Ruby style now enforced with Rubocop - [@dblock](https://github.com/dblock).
456
-
457
473
  ## [2.0.5] - 2013-05-10
458
474
 
459
475
  [2.0.5]: https://github.com/hashie/hashie/compare/v2.0.4...v2.0.5
@@ -470,7 +486,7 @@ Note: This version introduces several backward incompatible API changes. See [UP
470
486
 
471
487
  * [#94](https://github.com/hashie/hashie/pull/94): Made #fetch method consistent with normal Hash - [@markiz](https://github.com/markiz).
472
488
 
473
- ### Miscellaneous
489
+ ### Changed
474
490
 
475
491
  * [#90](https://github.com/hashie/hashie/pull/90): Various doc tweaks - [@craiglittle](https://github.com/craiglittle).
476
492
 
@@ -498,10 +514,7 @@ Note: This version introduces several backward incompatible API changes. See [UP
498
514
  ### Removed
499
515
 
500
516
  * [#81](https://github.com/hashie/hashie/pull/81): Removed Mash#object_id override - [@matschaffer](https://github.com/matschaffer).
501
-
502
- ### Miscellaneous
503
-
504
- * Gem cleanup: removed VERSION, Gemfile.lock - [@jch](https://github.com/jch), [@mbleigh](https://github.com/mbleigh).
517
+ * Removed VERSION and Gemfile.lock - [@jch](https://github.com/jch), [@mbleigh](https://github.com/mbleigh).
505
518
 
506
519
  ## [2.0.0] - 2013-02-16
507
520
 
@@ -511,6 +524,7 @@ Note: This version introduces several backward incompatible API changes. See [UP
511
524
 
512
525
  * [#41](https://github.com/hashie/hashie/pull/41): DeepMerge extension - [@nashby](https://github.com/nashby).
513
526
  * [#78](https://github.com/hashie/hashie/pull/78): Merge and update accepts a block - [@jch](https://github.com/jch).
527
+ * [#72](https://github.com/hashie/hashie/pull/72): Updated gemspec with license info - [@jordimassaguerpla](https://github.com/jordimassaguerpla).
514
528
 
515
529
  ### Changed
516
530
 
@@ -525,7 +539,3 @@ Note: This version introduces several backward incompatible API changes. See [UP
525
539
  * [#62](https://github.com/hashie/hashie/pull/62): Updated respond_to? method signature to match ruby core definition - [@dlupu](https://github.com/dlupu).
526
540
  * [#63](https://github.com/hashie/hashie/pull/63): Dash defaults are dup'ed before assigned - [@ohrite](https://github.com/ohrite).
527
541
  * [#66](https://github.com/hashie/hashie/pull/66): Mash#fetch works with symbol or string keys - [@arthwood](https://github.com/arthwood).
528
-
529
- ### Miscellaneous
530
-
531
- * [#72](https://github.com/hashie/hashie/pull/72): Updated gemspec with license info - [@jordimassaguerpla](https://github.com/jordimassaguerpla).
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2009 Intridea, Inc., and Contributors
1
+ Copyright (c) 2009-2020 Intridea, Inc., and Contributors.
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -2,11 +2,55 @@
2
2
 
3
3
  [![Join the chat at https://gitter.im/hashie/hashie](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/hashie/hashie?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
4
4
  [![Gem Version](http://img.shields.io/gem/v/hashie.svg)](http://badge.fury.io/rb/hashie)
5
- [![Build Status](http://img.shields.io/travis/hashie/hashie.svg)](https://travis-ci.org/hashie/hashie)
6
- [![Test Coverage](https://api.codeclimate.com/v1/badges/7a0b42c8a22c945571fd/test_coverage)](https://codeclimate.com/github/hashie/hashie/test_coverage)
7
- [![Maintainability](https://api.codeclimate.com/v1/badges/7a0b42c8a22c945571fd/maintainability)](https://codeclimate.com/github/hashie/hashie/maintainability)
8
-
9
- Hashie is a growing collection of tools that extend Hashes and make them more useful.
5
+ [![Build Status](https://github.com/hashie/hashie/actions/workflows/main.yml/badge.svg)](https://github.com/hashie/hashie/actions/workflows/main.yml)
6
+
7
+ [![eierlegende Wollmilchsau](./mascot.svg)](#mascot) Hashie is a growing collection of tools that extend Hashes and make them more useful.
8
+
9
+ # Table of Contents
10
+
11
+ - [Hashie](#hashie)
12
+ - [Table of Contents](#table-of-contents)
13
+ - [Installation](#installation)
14
+ - [Stable Release](#stable-release)
15
+ - [Hash Extensions](#hash-extensions)
16
+ - [Logging](#logging)
17
+ - [Coercion](#coercion)
18
+ - [Coercing Collections](#coercing-collections)
19
+ - [Coercing Hashes](#coercing-hashes)
20
+ - [Coercing Core Types](#coercing-core-types)
21
+ - [Coercion Proc](#coercion-proc)
22
+ - [A note on circular coercion](#a-note-on-circular-coercion)
23
+ - [KeyConversion](#keyconversion)
24
+ - [MergeInitializer](#mergeinitializer)
25
+ - [MethodAccess](#methodaccess)
26
+ - [MethodAccessWithOverride](#methodaccesswithoverride)
27
+ - [MethodOverridingInitializer](#methodoverridinginitializer)
28
+ - [IndifferentAccess](#indifferentaccess)
29
+ - [IgnoreUndeclared](#ignoreundeclared)
30
+ - [DeepMerge](#deepmerge)
31
+ - [DeepFetch](#deepfetch)
32
+ - [DeepFind](#deepfind)
33
+ - [DeepLocate](#deeplocate)
34
+ - [StrictKeyAccess](#strictkeyaccess)
35
+ - [Mash](#mash)
36
+ - [KeepOriginalKeys](#keeporiginalkeys)
37
+ - [PermissiveRespondTo](#permissiverespondto)
38
+ - [SafeAssignment](#safeassignment)
39
+ - [SymbolizeKeys](#symbolizekeys)
40
+ - [DefineAccessors](#defineaccessors)
41
+ - [Dash](#dash)
42
+ - [Potential Gotchas](#potential-gotchas)
43
+ - [PropertyTranslation](#propertytranslation)
44
+ - [Mash and Rails 4 Strong Parameters](#mash-and-rails-4-strong-parameters)
45
+ - [Coercion](#coercion-1)
46
+ - [PredefinedValues](#predefinedvalues)
47
+ - [Trash](#trash)
48
+ - [Clash](#clash)
49
+ - [Rash](#rash)
50
+ - [Auto-Optimized](#auto-optimized)
51
+ - [Mascot](#mascot)
52
+ - [Contributing](#contributing)
53
+ - [Copyright](#copyright)
10
54
 
11
55
  ## Installation
12
56
 
@@ -18,7 +62,7 @@ $ gem install hashie
18
62
 
19
63
  ## Stable Release
20
64
 
21
- You're reading the documentation for the stable release of Hashie, 4.1.0.(https://github.com/hashie/hashie/blob/v4.1.0/README.md).
65
+ You're reading the documentation for the stable release of Hashie, v5.0.0.
22
66
 
23
67
  ## Hash Extensions
24
68
 
@@ -190,13 +234,13 @@ end
190
234
 
191
235
  ### KeyConversion
192
236
 
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).
237
+ 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`.
194
238
 
195
239
  Hashie also has a utility method for converting keys on a Hash without a mixin:
196
240
 
197
241
  ```ruby
198
- Hashie.symbolize_keys! hash # => Symbolizes keys of hash.
199
- Hashie.symbolize_keys hash # => Returns a copy of hash with keys symbolized.
242
+ Hashie.symbolize_keys! hash # => Symbolizes all string keys of hash.
243
+ Hashie.symbolize_keys hash # => Returns a copy of hash with string keys symbolized.
200
244
  Hashie.stringify_keys! hash # => Stringifies keys of hash.
201
245
  Hashie.stringify_keys hash # => Returns a copy of hash with keys stringified.
202
246
  ```
@@ -269,8 +313,6 @@ This extension can be mixed in to your Hash subclass to allow you to use Strings
269
313
 
270
314
  In addition, IndifferentAccess will also inject itself into sub-hashes so they behave the same.
271
315
 
272
- Example:
273
-
274
316
  ```ruby
275
317
  class MyHash < Hash
276
318
  include Hashie::Extensions::MergeInitializer
@@ -290,6 +332,18 @@ myhash['fishes'][:food] = 'flakes'
290
332
  myhash['fishes']['food'] # => "flakes"
291
333
  ```
292
334
 
335
+ To get back a normal, not-indifferent Hash, you can use `#to_hash` on the indifferent hash. It exports the keys as strings, not symbols:
336
+
337
+ ```ruby
338
+ myhash = MyHash.new
339
+ myhash["foo"] = "bar"
340
+ myhash[:foo] #=> "bar"
341
+
342
+ normal_hash = myhash.to_hash
343
+ myhash["foo"] #=> "bar"
344
+ myhash[:foo] #=> nil
345
+ ```
346
+
293
347
  ### IgnoreUndeclared
294
348
 
295
349
  This extension can be mixed in to silently ignore undeclared properties on initialization instead of raising an error. This is useful when using a Trash to capture a subset of a larger hash.
@@ -445,8 +499,6 @@ books.deep_locate -> (key, value, object) { key == :pages && value <= 120 }
445
499
 
446
500
  This extension can be mixed in to allow a Hash to raise an error when attempting to extract a value using a non-existent key.
447
501
 
448
- ### Example:
449
-
450
502
  ```ruby
451
503
  class StrictKeyAccessHash < Hash
452
504
  include Hashie::Extensions::StrictKeyAccess
@@ -464,8 +516,6 @@ end
464
516
 
465
517
  Mash is an extended Hash that gives simple pseudo-object functionality that can be built from hashes and easily extended. It is intended to give the user easier access to the objects within the Mash through a property-like syntax, while still retaining all Hash functionality.
466
518
 
467
- ### Example:
468
-
469
519
  ```ruby
470
520
  mash = Hashie::Mash.new
471
521
  mash.name? # => false
@@ -488,12 +538,10 @@ mash.inspect # => <Hashie::Mash>
488
538
 
489
539
  **Note:** The `?` method will return false if a key has been set to false or nil. In order to check if a key has been set at all, use the `mash.key?('some_key')` method instead.
490
540
 
491
- ### How does Mash handle conflicts with pre-existing methods?
541
+ _How does Mash handle conflicts with pre-existing methods?_
492
542
 
493
543
  Please note that a Mash will not override methods through the use of the property-like syntax. This can lead to confusion if you expect to be able to access a Mash value through the property-like syntax for a key that conflicts with a method name. However, it protects users of your library from the unexpected behavior of those methods being overridden behind the scenes.
494
544
 
495
- #### Example:
496
-
497
545
  ```ruby
498
546
  mash = Hashie::Mash.new
499
547
  mash.name = "My Mash"
@@ -564,12 +612,10 @@ Hashie::Mash.quiet.new(zip: '90210', compact: true) # no errors logged
564
612
  Hashie::Mash.quiet(:zip).new(zip: '90210', compact: true) # error logged for compact
565
613
  ```
566
614
 
567
- ### How does the wrapping of Mash sub-Hashes work?
615
+ _How does the wrapping of Mash sub-Hashes work?_
568
616
 
569
617
  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.
570
618
 
571
- #### Example:
572
-
573
619
  ```ruby
574
620
  mash = Hashie::Mash.new(name: "Hashie", dependencies: { rake: "< 11", rspec: "~> 3.0" })
575
621
  mash.dependencies.class #=> Hashie::Mash
@@ -579,11 +625,20 @@ my_gem = MyGem.new(name: "Hashie", dependencies: { rake: "< 11", rspec: "~> 3.0"
579
625
  my_gem.dependencies.class #=> MyGem
580
626
  ```
581
627
 
582
- ### What else can Mash do?
628
+ _How does Mash handle key types which cannot be symbolized?_
583
629
 
584
- Mash allows you also to transform any files into a Mash objects.
630
+ Mash preserves keys which cannot be converted *directly* to both a string and a symbol, such as numeric keys. Since Mash is conceived to provide psuedo-object functionality, handling keys which cannot represent a method call falls outside its scope of value.
631
+
632
+ ```ruby
633
+ Hashie::Mash.new('1' => 'one string', :'1' => 'one sym', 1 => 'one num')
634
+ # => {"1"=>"one sym", 1=>"one num"}
635
+ ```
636
+
637
+ The symbol key `:'1'` is converted the string `'1'` to support indifferent access and consequently its value `'one sym'` will override the previously set `'one string'`. However, the subsequent key of `1` cannot directly convert to a symbol and therefore **not** converted to the string `'1'` that would otherwise override the previously set value of `'one sym'`.
585
638
 
586
- #### Example:
639
+ _What else can Mash do?_
640
+
641
+ Mash allows you also to transform any files into a Mash objects.
587
642
 
588
643
  ```yml
589
644
  #/etc/config/settings/twitter.yml
@@ -639,9 +694,9 @@ Specify `permitted_symbols`, `permitted_classes` and `aliases` options as needed
639
694
  Mash.load('data/user.csv', permitted_classes: [Symbol], permitted_symbols: [], aliases: false)
640
695
  ```
641
696
 
642
- ### Mash Extension: KeepOriginalKeys
697
+ ### KeepOriginalKeys
643
698
 
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.
699
+ This extension can be mixed into a Mash to keep the form of any keys passed directly into the Mash. By default, Mash converts symbol 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.
645
700
 
646
701
  ```ruby
647
702
  class KeepingMash < ::Hashie::Mash
@@ -658,7 +713,7 @@ mash['string_key'] #=> 'string'
658
713
  mash[:string_key] #=> 'string'
659
714
  ```
660
715
 
661
- ### Mash Extension: PermissiveRespondTo
716
+ ### PermissiveRespondTo
662
717
 
663
718
  By default, Mash only states that it responds to built-in methods, affixed methods (e.g. setters, underbangs, etc.), and keys that it currently contains. That means it won't state that it responds to a getter for an unset key, as in the following example:
664
719
 
@@ -682,12 +737,10 @@ mash.respond_to? :b #=> true
682
737
 
683
738
  This comes at the cost of approximately 20% performance for initialization and setters and 19KB of permanent memory growth for each such class that you create.
684
739
 
685
- ### Mash Extension: SafeAssignment
740
+ ### SafeAssignment
686
741
 
687
742
  This extension can be mixed into a Mash to guard the attempted overwriting of methods by property setters. When mixed in, the Mash will raise an `ArgumentError` if you attempt to write a property with the same name as an existing method.
688
743
 
689
- #### Example:
690
-
691
744
  ```ruby
692
745
  class SafeMash < ::Hashie::Mash
693
746
  include Hashie::Extensions::Mash::SafeAssignment
@@ -698,9 +751,9 @@ safe_mash.zip = 'Test' # => ArgumentError
698
751
  safe_mash[:zip] = 'test' # => still ArgumentError
699
752
  ```
700
753
 
701
- ### Mash Extension: SymbolizeKeys
754
+ ### SymbolizeKeys
702
755
 
703
- 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.
756
+ 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 string keys to symbols. It can be useful to use with keywords argument, which required symbol keys.
704
757
 
705
758
  ```ruby
706
759
  class SymbolizedMash < ::Hashie::Mash
@@ -731,7 +784,7 @@ end
731
784
 
732
785
  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.
733
786
 
734
- ### Mash Extension: DefineAccessors
787
+ ### DefineAccessors
735
788
 
736
789
  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.
737
790
 
@@ -762,8 +815,6 @@ Dash is an extended Hash that has a discrete set of defined properties and only
762
815
 
763
816
  You can also conditionally require certain properties by passing a Proc or Symbol. If a Proc is provided, it will be run in the context of the Dash instance. If a Symbol is provided, the value returned for the property or method of the same name will be evaluated. The property will be required if the result of the conditional is truthy.
764
817
 
765
- ### Example:
766
-
767
818
  ```ruby
768
819
  class Person < Hashie::Dash
769
820
  property :name, required: true
@@ -800,8 +851,6 @@ p.occupation # => 'Rubyist'
800
851
 
801
852
  Properties defined as symbols are not the same thing as properties defined as strings.
802
853
 
803
- ### Example:
804
-
805
854
  ```ruby
806
855
  class Tricky < Hashie::Dash
807
856
  property :trick
@@ -825,7 +874,28 @@ p = Tricky.new('trick' => 'two')
825
874
  p.trick # => NoMethodError
826
875
  ```
827
876
 
828
- ### Potential gotchas
877
+ If you would like to update a Dash and use any default values set in the case of a `nil` value, use `#update_attributes!`.
878
+
879
+ ```ruby
880
+ class WithDefaults < Hashie::Dash
881
+ property :description, default: 'none'
882
+ end
883
+
884
+ dash = WithDefaults.new
885
+ dash.description #=> 'none'
886
+
887
+ dash.description = 'You committed one of the classic blunders!'
888
+ dash.description #=> 'You committed one of the classic blunders!'
889
+
890
+ dash.description = nil
891
+ dash.description #=> nil
892
+
893
+ dash.description = 'Only slightly less known is ...'
894
+ dash.update_attributes!(description: nil)
895
+ dash.description #=> 'none'
896
+ ```
897
+
898
+ ### Potential Gotchas
829
899
 
830
900
  Because Dashes are subclasses of the built-in Ruby Hash class, the double-splat operator takes the Dash as-is without any conversion. This can lead to strange behavior when you use the double-splat operator on a Dash as the first part of a keyword list or built Hash. For example:
831
901
 
@@ -857,13 +927,11 @@ qux.is_a?(Hash) #=> true
857
927
  qux[:quux] #=> "corge"
858
928
  ```
859
929
 
860
- ### Dash Extension: PropertyTranslation
930
+ ### PropertyTranslation
861
931
 
862
932
  The `Hashie::Extensions::Dash::PropertyTranslation` mixin extends a Dash with
863
933
  the ability to remap keys from a source hash.
864
934
 
865
- ### Example from inconsistent APIs
866
-
867
935
  Property translation is useful when you need to read data from another
868
936
  application -- such as a Java API -- where the keys are named differently from
869
937
  Ruby conventions.
@@ -883,8 +951,6 @@ person[:first_name] #=> 'Michael'
883
951
  person[:last_name] #=> 'Bleigh
884
952
  ```
885
953
 
886
- ### Example using translation lambdas
887
-
888
954
  You can also use a lambda to translate the value. This is particularly useful
889
955
  when you want to ensure the type of data you're wrapping.
890
956
 
@@ -905,7 +971,7 @@ model.created_at.class #=> Time
905
971
 
906
972
  To enable compatibility with Rails 4 use the [hashie-forbidden_attributes](https://github.com/Maxim-Filimonov/hashie-forbidden_attributes) gem.
907
973
 
908
- ### Dash Extension: Coercion.
974
+ ### Coercion
909
975
 
910
976
  If you want to use `Hashie::Extensions::Coercion` together with `Dash` then
911
977
  you may probably want to use `Hashie::Extensions::Dash::Coercion` instead.
@@ -935,6 +1001,20 @@ class UserHash < Hashie::Dash
935
1001
  end
936
1002
  ```
937
1003
 
1004
+ ### PredefinedValues
1005
+
1006
+ The `Hashie::Extensions::Dash::PredefinedValues` mixin extends a Dash with
1007
+ the ability to accept predefined values on a property.
1008
+
1009
+ ```ruby
1010
+ class UserHash < Hashie::Dash
1011
+ include Hashie::Extensions::Dash::PredefinedValues
1012
+
1013
+ property :gender, values: %i[male female prefer_not_to_say]
1014
+ property :age, values: (0..150)
1015
+ end
1016
+ ```
1017
+
938
1018
  ## Trash
939
1019
 
940
1020
  A Trash is a Dash that allows you to translate keys on initialization. It mixes
@@ -976,8 +1056,6 @@ Clash is a Chainable Lazy Hash that allows you to easily construct complex hashe
976
1056
 
977
1057
  Essentially, a Clash is a generalized way to provide much of the same kind of "chainability" that libraries like Arel or Rails 2.x's named_scopes provide.
978
1058
 
979
- ### Example:
980
-
981
1059
  ```ruby
982
1060
  c = Hashie::Clash.new
983
1061
  c.where(abc: 'def').order(:created_at)
@@ -1003,8 +1081,6 @@ A good use case for the Rash is an URL router for a web framework, where URLs ne
1003
1081
 
1004
1082
  If the Rash's value is a `proc`, the `proc` will be automatically called with the regexp's MatchData (matched groups) as a block argument.
1005
1083
 
1006
- ### Example:
1007
-
1008
1084
  ```ruby
1009
1085
 
1010
1086
  # Mapping names to appropriate greetings
@@ -1021,18 +1097,21 @@ mapper["I like traffic lights"] # => "Who DOESN'T like traffic lights?!"
1021
1097
  mapper["Get off my lawn!"] # => "Forget your lawn, old man!"
1022
1098
  ```
1023
1099
 
1024
- ### Auto-optimized
1100
+ ### Auto-Optimized
1025
1101
 
1026
1102
  **Note:** The Rash is automatically optimized every 500 accesses (which means that it sorts the list of Regexps, putting the most frequently matched ones at the beginning).
1027
1103
 
1028
1104
  If this value is too low or too high for your needs, you can tune it by setting: `rash.optimize_every = n`.
1029
1105
 
1106
+ ## Mascot
1107
+ [![eierlegende Wollmilchsau](./mascot.svg)](https://en.wiktionary.org/wiki/eierlegende_Wollmilchsau) Meet Hashie's "offical" mascot, the [eierlegende Wollmilchsau](https://en.wiktionary.org/wiki/eierlegende_Wollmilchsau)!
1108
+
1030
1109
  ## Contributing
1031
1110
 
1032
1111
  See [CONTRIBUTING.md](CONTRIBUTING.md)
1033
1112
 
1034
1113
  ## Copyright
1035
1114
 
1036
- Copyright (c) 2009-2014 Intridea, Inc. (http://intridea.com/) and [contributors](https://github.com/hashie/hashie/graphs/contributors).
1115
+ Copyright (c) 2009-2020 [Intridea, Inc.](http://intridea.com), and [contributors](https://github.com/hashie/hashie/graphs/contributors).
1037
1116
 
1038
1117
  MIT License. See [LICENSE](LICENSE) for details.
data/UPGRADING.md CHANGED
@@ -1,6 +1,44 @@
1
1
  Upgrading Hashie
2
2
  ================
3
3
 
4
+ ### Upgrading to 5.0.0
5
+
6
+ #### Mash initialization key conversion
7
+
8
+ Mash initialization now only converts to string keys which can be represented as symbols.
9
+
10
+ ```ruby
11
+ Hashie::Mash.new(
12
+ {foo: "bar"} => "baz",
13
+ "1" => "one string",
14
+ :"1" => "one sym",
15
+ 1 => "one num"
16
+ )
17
+
18
+ # Before
19
+ {"{:foo=>\"bar\"}"=>"baz", "1"=>"one num"}
20
+
21
+ # After
22
+ {{:foo=>"bar"}=>"baz", "1"=>"one sym", 1=>"one num"}
23
+ ```
24
+
25
+ #### Mash#dig with numeric keys
26
+
27
+ `Hashie::Mash#dig` no longer considers numeric keys for indifferent access.
28
+
29
+ ```ruby
30
+ my_mash = Hashie::Mash.new("1" => "a") # => {"1"=>"a"}
31
+
32
+ my_mash.dig("1") # => "a"
33
+ my_mash.dig(:"1") # => "a"
34
+
35
+ # Before
36
+ my_mash.dig(1) # => "a"
37
+
38
+ # After
39
+ my_mash.dig(1) # => nil
40
+ ```
41
+
4
42
  ### Upgrading to 4.0.0
5
43
 
6
44
  #### Non-destructive Hash methods called on Mash
data/lib/hashie/dash.rb CHANGED
@@ -104,19 +104,6 @@ module Hashie
104
104
  def initialize(attributes = {}, &block)
105
105
  super(&block)
106
106
 
107
- self.class.defaults.each_pair do |prop, value|
108
- self[prop] = begin
109
- val = value.dup
110
- if val.is_a?(Proc)
111
- val.arity == 1 ? val.call(self) : val.call
112
- else
113
- val
114
- end
115
- rescue TypeError
116
- value
117
- end
118
- end
119
-
120
107
  initialize_attributes(attributes)
121
108
  assert_required_attributes_set!
122
109
  end
@@ -169,17 +156,30 @@ module Hashie
169
156
  self
170
157
  end
171
158
 
159
+ def to_h
160
+ defaults = ::Hash[self.class.properties.map { |prop| [prop, self.class.defaults[prop]] }]
161
+
162
+ defaults.merge(self)
163
+ end
164
+ alias to_hash to_h
165
+
172
166
  def update_attributes!(attributes)
173
167
  update_attributes(attributes)
174
168
 
175
169
  self.class.defaults.each_pair do |prop, value|
176
- next unless self[prop].nil?
170
+ next unless fetch(prop, nil).nil?
177
171
  self[prop] = begin
178
- value.dup
172
+ val = value.dup
173
+ if val.is_a?(Proc)
174
+ val.arity == 1 ? val.call(self) : val.call
175
+ else
176
+ val
177
+ end
179
178
  rescue TypeError
180
179
  value
181
180
  end
182
181
  end
182
+
183
183
  assert_required_attributes_set!
184
184
  end
185
185
 
@@ -189,7 +189,7 @@ module Hashie
189
189
  return unless attributes
190
190
 
191
191
  cleaned_attributes = attributes.reject { |_attr, value| value.nil? }
192
- update_attributes(cleaned_attributes)
192
+ update_attributes!(cleaned_attributes)
193
193
  end
194
194
 
195
195
  def update_attributes(attributes)
@@ -19,6 +19,15 @@ module Hashie
19
19
  end
20
20
  private_class_method :requires_class_methods?
21
21
 
22
+ def to_h
23
+ defaults = ::Hash[self.class.properties.map do |prop|
24
+ [Hashie::Extensions::IndifferentAccess.convert_key(prop), self.class.defaults[prop]]
25
+ end]
26
+
27
+ defaults.merge(self)
28
+ end
29
+ alias to_hash to_h
30
+
22
31
  module ClassMethods
23
32
  # Check to see if the specified property has already been
24
33
  # defined.
@@ -0,0 +1,88 @@
1
+ module Hashie
2
+ module Extensions
3
+ module Dash
4
+ # Extends a Dash with the ability to accept only predefined values on a property.
5
+ #
6
+ # == Example
7
+ #
8
+ # class PersonHash < Hashie::Dash
9
+ # include Hashie::Extensions::Dash::PredefinedValues
10
+ #
11
+ # property :gender, values: [:male, :female, :prefer_not_to_say]
12
+ # property :age, values: (0..150) # a Range
13
+ # end
14
+ #
15
+ # person = PersonHash.new(gender: :male, age: -1)
16
+ # # => ArgumentError: The value '-1' is not accepted for property 'age'
17
+ module PredefinedValues
18
+ def self.included(base)
19
+ base.instance_variable_set(:@values_for_properties, {})
20
+ base.extend(ClassMethods)
21
+ base.include(InstanceMethods)
22
+ end
23
+
24
+ module ClassMethods
25
+ attr_reader :values_for_properties
26
+
27
+ def inherited(klass)
28
+ super
29
+ klass.instance_variable_set(:@values_for_properties, values_for_properties.dup)
30
+ end
31
+
32
+ def property(property_name, options = {})
33
+ super
34
+
35
+ return unless (predefined_values = options[:values])
36
+
37
+ assert_predefined_values!(predefined_values)
38
+ set_predefined_values(property_name, predefined_values)
39
+ end
40
+
41
+ private
42
+
43
+ def assert_predefined_values!(predefined_values)
44
+ return if supported_type?(predefined_values)
45
+
46
+ raise ArgumentError, %(`values` accepts an Array or a Range.)
47
+ end
48
+
49
+ def supported_type?(predefined_values)
50
+ [::Array, ::Range].any? { |klass| predefined_values.is_a?(klass) }
51
+ end
52
+
53
+ def set_predefined_values(property_name, predefined_values)
54
+ @values_for_properties[property_name] = predefined_values
55
+ end
56
+ end
57
+
58
+ module InstanceMethods
59
+ def initialize(*)
60
+ super
61
+
62
+ assert_property_values!
63
+ end
64
+
65
+ private
66
+
67
+ def assert_property_values!
68
+ self.class.values_for_properties.each_key do |property|
69
+ value = send(property)
70
+
71
+ if value && !values_for_properties(property).include?(value)
72
+ fail_property_value_error!(property)
73
+ end
74
+ end
75
+ end
76
+
77
+ def fail_property_value_error!(property)
78
+ raise ArgumentError, "Invalid value for property '#{property}'"
79
+ end
80
+
81
+ def values_for_properties(property)
82
+ self.class.values_for_properties[property]
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -153,7 +153,12 @@ module Hashie
153
153
  def []=(property, value)
154
154
  if self.class.translation_exists? property
155
155
  send("#{property}=", value)
156
- super(property, value) if self.class.properties.include?(property)
156
+
157
+ if self.class.transformation_exists? property
158
+ super property, self.class.transformed_property(property, value)
159
+ elsif self.class.properties.include?(property)
160
+ super(property, value)
161
+ end
157
162
  elsif self.class.transformation_exists? property
158
163
  super property, self.class.transformed_property(property, value)
159
164
  elsif property_exists? property
@@ -31,12 +31,11 @@ module Hashie
31
31
  module IgnoreUndeclared
32
32
  def initialize_attributes(attributes)
33
33
  return unless attributes
34
+
34
35
  klass = self.class
35
- translations = klass.respond_to?(:translations) && klass.translations
36
- attributes.each_pair do |att, value|
37
- next unless klass.property?(att) || (translations && translations.include?(att))
38
- self[att] = value
39
- end
36
+ translations = klass.respond_to?(:translations) && klass.translations || []
37
+
38
+ super(attributes.select { |attr, _| klass.property?(attr) || translations.include?(attr) })
40
39
  end
41
40
 
42
41
  def property_exists?(property)
@@ -23,6 +23,13 @@ module Hashie
23
23
  # h['baz'] # => 'blip'
24
24
  #
25
25
  module IndifferentAccess
26
+ include Hashie::Extensions::RubyVersionCheck
27
+
28
+ # @api private
29
+ def self.convert_key(key)
30
+ key.to_s
31
+ end
32
+
26
33
  def self.included(base)
27
34
  Hashie::Extensions::Dash::IndifferentAccess.maybe_extend(base)
28
35
 
@@ -66,7 +73,7 @@ module Hashie
66
73
  end
67
74
 
68
75
  def convert_key(key)
69
- key.to_s
76
+ IndifferentAccess.convert_key(key)
70
77
  end
71
78
 
72
79
  # Iterates through the keys and values, reconverting them to
@@ -74,7 +81,7 @@ module Hashie
74
81
  # is injecting itself into member hashes.
75
82
  def convert!
76
83
  keys.each do |k| # rubocop:disable Performance/HashEachMethods
77
- regular_writer convert_key(k), indifferent_value(regular_delete(k))
84
+ indifferent_writer k, regular_delete(k)
78
85
  end
79
86
  self
80
87
  end
@@ -133,7 +140,7 @@ module Hashie
133
140
 
134
141
  def merge(*args)
135
142
  result = super
136
- IndifferentAccess.inject!(result) if hash_lacking_indifference?(result)
143
+ return IndifferentAccess.inject!(result) if hash_lacking_indifference?(result)
137
144
  result.convert!
138
145
  end
139
146
 
@@ -141,6 +148,32 @@ module Hashie
141
148
  super.convert!
142
149
  end
143
150
 
151
+ def to_hash
152
+ {}.tap do |result|
153
+ each_pair { |key, value| result[key] = value }
154
+
155
+ if default_proc
156
+ result.default_proc = default_proc
157
+ else
158
+ result.default = default
159
+ end
160
+ end
161
+ end
162
+
163
+ with_minimum_ruby('2.5.0') do
164
+ def slice(*keys)
165
+ string_keys = keys.map { |key| convert_key(key) }
166
+ super(*string_keys)
167
+ end
168
+ end
169
+
170
+ with_minimum_ruby('3.0.0') do
171
+ def except(*keys)
172
+ string_keys = keys.map { |key| convert_key(key) }
173
+ super(*string_keys)
174
+ end
175
+ end
176
+
144
177
  protected
145
178
 
146
179
  def hash_lacking_indifference?(other)
@@ -5,7 +5,7 @@ module Hashie
5
5
  #
6
6
  # @example
7
7
  # class LazyResponse < Hashie::Mash
8
- # include Hashie::Extensions::Mash::SymbolizedKeys
8
+ # include Hashie::Extensions::Mash::SymbolizeKeys
9
9
  # end
10
10
  #
11
11
  # response = LazyResponse.new("id" => 123, "name" => "Rey").to_h
@@ -24,13 +24,13 @@ module Hashie
24
24
 
25
25
  private
26
26
 
27
- # Converts a key to a symbol
27
+ # Converts a key to a symbol, if possible
28
28
  #
29
29
  # @api private
30
- # @param [String, Symbol] key the key to convert to a symbol
31
- # @return [void]
30
+ # @param [<K>] key the key to attempt convert to a symbol
31
+ # @return [Symbol, K]
32
32
  def convert_key(key)
33
- key.to_sym
33
+ key.respond_to?(:to_sym) ? key.to_sym : key
34
34
  end
35
35
  end
36
36
  end
@@ -46,7 +46,7 @@ module Hashie
46
46
  hash.extend(Hashie::Extensions::SymbolizeKeys) unless hash.respond_to?(:symbolize_keys!)
47
47
  hash.keys.each do |k| # rubocop:disable Performance/HashEachMethods
48
48
  symbolize_keys_recursively!(hash[k])
49
- hash[k.to_sym] = hash.delete(k)
49
+ hash[convert_key(k)] = hash.delete(k)
50
50
  end
51
51
  hash
52
52
  end
@@ -61,6 +61,17 @@ module Hashie
61
61
  symbolize_keys!(new_hash)
62
62
  end
63
63
  end
64
+
65
+ private
66
+
67
+ # Converts a key to a symbol, if possible
68
+ #
69
+ # @api private
70
+ # @param [<K>] key the key to attempt convert to a symbol
71
+ # @return [Symbol, K]
72
+ def convert_key(key)
73
+ key.respond_to?(:to_sym) ? key.to_sym : key
74
+ end
64
75
  end
65
76
 
66
77
  class << self
data/lib/hashie/hash.rb CHANGED
@@ -21,8 +21,8 @@ module Hashie
21
21
  assignment_key =
22
22
  if options[:stringify_keys]
23
23
  k.to_s
24
- elsif options[:symbolize_keys]
25
- k.to_s.to_sym
24
+ elsif options[:symbolize_keys] && k.respond_to?(:to_sym)
25
+ k.to_sym
26
26
  else
27
27
  k
28
28
  end
data/lib/hashie/mash.rb CHANGED
@@ -62,7 +62,6 @@ module Hashie
62
62
  # mash.author # => <Mash>
63
63
  #
64
64
  class Mash < Hash
65
- include Hashie::Extensions::PrettyInspect
66
65
  include Hashie::Extensions::RubyVersionCheck
67
66
  extend Hashie::Extensions::KeyConflictWarning
68
67
 
@@ -121,8 +120,8 @@ module Hashie
121
120
  alias regular_reader []
122
121
  alias regular_writer []=
123
122
 
124
- # Retrieves an attribute set in the Mash. Will convert
125
- # any key passed in to a string before retrieving.
123
+ # Retrieves an attribute set in the Mash. Will convert a key passed in
124
+ # as a symbol to a string before retrieving.
126
125
  def custom_reader(key)
127
126
  default_proc.call(self, key) if default_proc && !key?(key)
128
127
  value = regular_reader(convert_key(key))
@@ -130,14 +129,12 @@ module Hashie
130
129
  value
131
130
  end
132
131
 
133
- # Sets an attribute in the Mash. Key will be converted to
134
- # a string before it is set, and Hashes will be converted
135
- # into Mashes for nesting purposes.
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.
136
135
  def custom_writer(key, value, convert = true) #:nodoc:
137
- key_as_symbol = (key = convert_key(key)).to_sym
138
-
139
- log_built_in_message(key_as_symbol) if log_collision?(key_as_symbol)
140
- regular_writer(key, convert ? convert_value(value) : value)
136
+ log_built_in_message(key) if key.respond_to?(:to_sym) && log_collision?(key.to_sym)
137
+ regular_writer(convert_key(key), convert ? convert_value(value) : value)
141
138
  end
142
139
 
143
140
  alias [] custom_reader
@@ -354,6 +351,13 @@ module Hashie
354
351
  end
355
352
  end
356
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
359
+ end
360
+
357
361
  protected
358
362
 
359
363
  def method_name_and_suffix(method_name)
@@ -371,7 +375,7 @@ module Hashie
371
375
  end
372
376
 
373
377
  def convert_key(key) #:nodoc:
374
- key.to_s
378
+ key.respond_to?(:to_sym) ? key.to_s : key
375
379
  end
376
380
 
377
381
  def convert_value(val, duping = false) #:nodoc:
@@ -406,6 +410,7 @@ module Hashie
406
410
  end
407
411
 
408
412
  def log_collision?(method_key)
413
+ return unless method_key.is_a?(String) || method_key.is_a?(Symbol)
409
414
  return unless respond_to?(method_key)
410
415
 
411
416
  _, suffix = method_name_and_suffix(method_key)
@@ -1,3 +1,3 @@
1
1
  module Hashie
2
- VERSION = '4.1.0'.freeze
2
+ VERSION = '5.0.0'.freeze
3
3
  end
data/lib/hashie.rb CHANGED
@@ -41,6 +41,7 @@ module Hashie
41
41
  autoload :IndifferentAccess, 'hashie/extensions/dash/indifferent_access'
42
42
  autoload :PropertyTranslation, 'hashie/extensions/dash/property_translation'
43
43
  autoload :Coercion, 'hashie/extensions/dash/coercion'
44
+ autoload :PredefinedValues, 'hashie/extensions/dash/predefined_values'
44
45
  end
45
46
 
46
47
  module Mash
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hashie
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.1.0
4
+ version: 5.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Bleigh
8
8
  - Jerry Cheung
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2020-02-01 00:00:00.000000000 Z
12
+ date: 2021-11-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -50,6 +50,7 @@ files:
50
50
  - lib/hashie/extensions/coercion.rb
51
51
  - lib/hashie/extensions/dash/coercion.rb
52
52
  - lib/hashie/extensions/dash/indifferent_access.rb
53
+ - lib/hashie/extensions/dash/predefined_values.rb
53
54
  - lib/hashie/extensions/dash/property_translation.rb
54
55
  - lib/hashie/extensions/deep_fetch.rb
55
56
  - lib/hashie/extensions/deep_find.rb
@@ -89,7 +90,7 @@ metadata:
89
90
  changelog_uri: https://github.com/hashie/hashie/blob/master/CHANGELOG.md
90
91
  documentation_uri: https://www.rubydoc.info/gems/hashie
91
92
  source_code_uri: https://github.com/hashie/hashie
92
- post_install_message:
93
+ post_install_message:
93
94
  rdoc_options: []
94
95
  require_paths:
95
96
  - lib
@@ -104,8 +105,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
104
105
  - !ruby/object:Gem::Version
105
106
  version: '0'
106
107
  requirements: []
107
- rubygems_version: 3.0.3
108
- signing_key:
108
+ rubygems_version: 3.1.3
109
+ signing_key:
109
110
  specification_version: 4
110
111
  summary: Your friendly neighborhood hash library.
111
112
  test_files: []