hashie 5.1.0 → 5.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +56 -0
- data/CONTRIBUTING.md +38 -1
- data/README.md +816 -181
- data/Rakefile +29 -1
- data/UPGRADING.md +18 -0
- data/hashie.gemspec +8 -7
- data/lib/hashie/array.rb +15 -12
- data/lib/hashie/clash.rb +59 -4
- data/lib/hashie/dash.rb +144 -16
- data/lib/hashie/extensions/active_support/core_ext/hash.rb +38 -0
- data/lib/hashie/extensions/array/pretty_inspect.rb +20 -0
- data/lib/hashie/extensions/block_access.rb +71 -0
- data/lib/hashie/extensions/coercion.rb +180 -19
- data/lib/hashie/extensions/dash/coercion.rb +34 -3
- data/lib/hashie/extensions/dash/indifferent_access.rb +83 -5
- data/lib/hashie/extensions/dash/lazy.rb +170 -0
- data/lib/hashie/extensions/dash/predefined_values.rb +69 -9
- data/lib/hashie/extensions/dash/property_translation.rb +134 -16
- data/lib/hashie/extensions/deep_fetch.rb +21 -9
- data/lib/hashie/extensions/deep_find.rb +20 -0
- data/lib/hashie/extensions/deep_grep.rb +69 -0
- data/lib/hashie/extensions/deep_locate.rb +15 -28
- data/lib/hashie/extensions/deep_merge.rb +16 -0
- data/lib/hashie/extensions/deep_merge_initializer.rb +42 -0
- data/lib/hashie/extensions/ignore_undeclared.rb +21 -3
- data/lib/hashie/extensions/indifferent_access.rb +100 -14
- data/lib/hashie/extensions/kernel_coercion.rb +58 -0
- data/lib/hashie/extensions/key_conflict_warning.rb +39 -4
- data/lib/hashie/extensions/key_conversion.rb +9 -0
- data/lib/hashie/extensions/mash/define_accessors.rb +71 -8
- data/lib/hashie/extensions/mash/keep_original_keys.rb +13 -9
- data/lib/hashie/extensions/mash/permissive_respond_to.rb +2 -0
- data/lib/hashie/extensions/mash/required_keys.rb +111 -0
- data/lib/hashie/extensions/mash/safe_assignment.rb +22 -4
- data/lib/hashie/extensions/mash/strict_key_access.rb +65 -0
- data/lib/hashie/extensions/mash/symbolize_keys.rb +6 -2
- data/lib/hashie/extensions/mash/transform_keys.rb +86 -0
- data/lib/hashie/extensions/mash/underscore_keys.rb +32 -0
- data/lib/hashie/extensions/merge_initializer.rb +9 -0
- data/lib/hashie/extensions/method_access.rb +93 -7
- data/lib/hashie/extensions/parsers/yaml_erb_parser.rb +28 -35
- data/lib/hashie/extensions/parsers/yaml_parser.rb +81 -0
- data/lib/hashie/extensions/persistable.rb +137 -0
- data/lib/hashie/extensions/pretty_inspect.rb +14 -0
- data/lib/hashie/extensions/ruby_version.rb +18 -1
- data/lib/hashie/extensions/ruby_version_check.rb +17 -0
- data/lib/hashie/extensions/strict_key_access.rb +59 -5
- data/lib/hashie/extensions/stringify_keys.rb +72 -17
- data/lib/hashie/extensions/symbolize_keys.rb +72 -16
- data/lib/hashie/hash.rb +16 -0
- data/lib/hashie/logger.rb +18 -1
- data/lib/hashie/mash.rb +293 -62
- data/lib/hashie/railtie.rb +27 -1
- data/lib/hashie/rash.rb +64 -4
- data/lib/hashie/trash.rb +8 -0
- data/lib/hashie/utils.rb +17 -6
- data/lib/hashie/version.rb +3 -1
- data/lib/hashie.rb +45 -0
- metadata +15 -17
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1623620401412d6612e1b7a1d2963cd9b31d584c3278987fafe45eac8cdd025b
|
|
4
|
+
data.tar.gz: f3bb1e89d55110e20bed0b5c76e6e9e817c1e99ad0fed2e7ee7c89cc948baaf8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: dea36ed10af73ca738634902bf043db652baa251b43066fcb9e309f28c501ac60ea843ef66944fd1b5a5801f37bac385bb2e165daeef9e62498f527387502e2e
|
|
7
|
+
data.tar.gz: 1131b72244560c35aaff3c6b3fcc28da13caa67c74b7c6f3dc6628c0cbe0ee74ae85429165d04988d1466ff045ee9198505c48192833ca249260cea3f2310dc8
|
data/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,62 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
Any violations of this scheme are considered to be bugs.
|
|
8
8
|
|
|
9
|
+
## [5.2.0] - 2026-10-23
|
|
10
|
+
|
|
11
|
+
[5.2.0]: https://github.com/hashie/hashie/compare/v5.1.0...v5.2.0
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
* [#644](https://github.com/hashie/hashie/pull/644): Added `rubocop-spellcheck` to the lint task for Ruby and documentation, with reviewed project vocabulary - [@dblock](https://github.com/dblock).
|
|
16
|
+
* [#636](https://github.com/hashie/hashie/pull/636): Added opt-in per-property lazy loaders for Dash and Trash, with transformations, coercion, defaults, and required-property validation deferred until access, following [#587](https://github.com/hashie/hashie/issues/587) - [@dblock](https://github.com/dblock).
|
|
17
|
+
* [#635](https://github.com/hashie/hashie/pull/635): Parse README Ruby examples with Kramdown and execute them in CI with isolated optional dependencies - [@dblock](https://github.com/dblock).
|
|
18
|
+
* [#623](https://github.com/hashie/hashie/pull/623): Documented Dash validation with ActiveModel and added integration coverage, following [#300](https://github.com/hashie/hashie/issues/300), reported by [@SkyCrawl](https://github.com/SkyCrawl), with the ActiveModel approach suggested by [@martinstreicher](https://github.com/martinstreicher) and endorsed by [@dblock](https://github.com/dblock).
|
|
19
|
+
* [#625](https://github.com/hashie/hashie/pull/625): Added an opt-in `YamlParser` that parses YAML without evaluating ERB, while preserving `Mash.load`'s existing ERB-enabled default for compatibility, following [#575](https://github.com/hashie/hashie/issues/575) - [@bo-tato](https://github.com/bo-tato), [@dblock](https://github.com/dblock).
|
|
20
|
+
* [#626](https://github.com/hashie/hashie/pull/626): Added executable YARD examples for every public class, module, and method, with public API example coverage enforced in Rake and CI, following the documentation work in [#421](https://github.com/hashie/hashie/pull/421) - [@michaelherold](https://github.com/michaelherold), [@dblock](https://github.com/dblock).
|
|
21
|
+
* [#621](https://github.com/hashie/hashie/pull/621): Added `Mash::UnderscoreKeys` on top of `TransformKeys` for camel-case and hyphenated key normalization, following [#566](https://github.com/hashie/hashie/pull/566) - [@arianf](https://github.com/arianf), [@dblock](https://github.com/dblock).
|
|
22
|
+
* [#620](https://github.com/hashie/hashie/pull/620): Added configurable `Mash::TransformKeys` key normalization as a foundation for [#566](https://github.com/hashie/hashie/pull/566) - [@arianf](https://github.com/arianf), [@dblock](https://github.com/dblock).
|
|
23
|
+
* [#618](https://github.com/hashie/hashie/pull/618): Added `Hashie::Extensions::DeepGrep` for regular-expression searches of nested hashes and arrays, following [#528](https://github.com/hashie/hashie/pull/528) - [@vmarutha](https://github.com/vmarutha), [@dblock](https://github.com/dblock).
|
|
24
|
+
* [#617](https://github.com/hashie/hashie/pull/617): Documented nil coercion bypass versus Dash defaults and added initialization, assignment, update, and inheritance regression coverage, following [#472](https://github.com/hashie/hashie/pull/472) - [@bobbytables](https://github.com/bobbytables), [@dblock](https://github.com/dblock).
|
|
25
|
+
* [#611](https://github.com/hashie/hashie/pull/611): Added callable coercers, including bound methods and dry-types objects, following [#379](https://github.com/hashie/hashie/pull/379) and [#239](https://github.com/hashie/hashie/issues/239) - [@mkcode](https://github.com/mkcode), [@dblock](https://github.com/dblock).
|
|
26
|
+
* [#612](https://github.com/hashie/hashie/pull/612): Added `Hashie::Extensions::DeepMergeInitializer` to recursively initialize Hash subclasses, including hashes inside arrays, following [#382](https://github.com/hashie/hashie/pull/382) - [@sazor](https://github.com/sazor), [@dblock](https://github.com/dblock).
|
|
27
|
+
* [#592](https://github.com/hashie/hashie/pull/592): Added support for Ruby 4.0 - [@dblock](https://github.com/dblock).
|
|
28
|
+
* [#595](https://github.com/hashie/hashie/pull/595): Added test coverage reporting with Coveralls - [@dblock](https://github.com/dblock).
|
|
29
|
+
* [#597](https://github.com/hashie/hashie/pull/597): Fixed coverage reporting to Coveralls to work on pull requests via `GITHUB_TOKEN` - [@dblock](https://github.com/dblock).
|
|
30
|
+
* [#599](https://github.com/hashie/hashie/pull/599): Added `Hashie::Extensions::Mash::StrictKeyAccess` to raise a `KeyError` for undefined keys, including in nested Mashes - [@dblock](https://github.com/dblock).
|
|
31
|
+
* [#601](https://github.com/hashie/hashie/pull/601): Added `Hashie::Extensions::KernelCoercion` to coerce core types using stricter `Kernel` methods (e.g. `Kernel#Integer`) instead of lenient conversion methods (e.g. `#to_i`) - [@dblock](https://github.com/dblock).
|
|
32
|
+
* [#605](https://github.com/hashie/hashie/pull/605): Added `Hashie::Extensions::Mash::RequiredKeys`, allowing a Mash to require specific keys to be set while still allowing arbitrary keys - [@dblock](https://github.com/dblock).
|
|
33
|
+
* [#608](https://github.com/hashie/hashie/pull/608): Added `Hashie::Extensions::BlockAccess` for block-style construction of nested hashes, completing [#109](https://github.com/hashie/hashie/pull/109) as a reusable extension - [@ryansouza](https://github.com/ryansouza), [@dblock](https://github.com/dblock).
|
|
34
|
+
* [#610](https://github.com/hashie/hashie/pull/610): Added opt-in `Hashie::Extensions::Persistable` for safe YAML loading and atomic file saves, following [#262](https://github.com/hashie/hashie/pull/262) - [@maxlinc](https://github.com/maxlinc), [@michaelherold](https://github.com/michaelherold), [@dblock](https://github.com/dblock).
|
|
35
|
+
|
|
36
|
+
### Changed
|
|
37
|
+
|
|
38
|
+
* [#630](https://github.com/hashie/hashie/pull/630): Enabled project-wide RuboCop with new cops, Rake and RSpec plugins, frozen string literals, autocorrections, and a refreshed baseline for remaining offenses - [@dblock](https://github.com/dblock).
|
|
39
|
+
* [#615](https://github.com/hashie/hashie/pull/615): Reduced allocations in Mash array conversion while preserving `Hashie::Array` behavior, and reused symbol names in indifferent and original-key access when available - [@dblock](https://github.com/dblock).
|
|
40
|
+
* [#607](https://github.com/hashie/hashie/pull/607): Standardized exception message casing and punctuation and enforced the convention with RuboCop - [@dblock](https://github.com/dblock).
|
|
41
|
+
* [#607](https://github.com/hashie/hashie/pull/607): Upgraded RuboCop to 1.91.0 and consolidated exception-message checks into one CI lint job - [@dblock](https://github.com/dblock).
|
|
42
|
+
* [#590](https://github.com/hashie/hashie/pull/590): Migrated Danger to use `danger-pr-comment` workflow - [@dblock](https://github.com/dblock).
|
|
43
|
+
* [#613](https://github.com/hashie/hashie/pull/613): `Mash` converts symbol keys with `Symbol#name` on Ruby 3.0+, so reads and writes with a symbol key no longer allocate a string - [@sampokuokkanen](https://github.com/sampokuokkanen).
|
|
44
|
+
|
|
45
|
+
### Removed
|
|
46
|
+
|
|
47
|
+
* Reverted [#619](https://github.com/hashie/hashie/pull/619)'s `deep_merge_new_hash` hook in favor of the breaking-change proposal in [#632](https://github.com/hashie/hashie/pull/632), which preserves incoming hash subclasses directly - [@dblock](https://github.com/dblock).
|
|
48
|
+
* [#622](https://github.com/hashie/hashie/pull/622): Dropped Ruby 2.7 support, raised the minimum to Ruby 3.0, and removed obsolete Ruby version gates and symbol-conversion fallbacks, following [#613](https://github.com/hashie/hashie/pull/613#issuecomment-6354118292) - [@dblock](https://github.com/dblock).
|
|
49
|
+
|
|
50
|
+
### Fixed
|
|
51
|
+
|
|
52
|
+
* [#642](https://github.com/hashie/hashie/pull/642): Fixed Clash Marshal serialization on MRI by no longer advertising unimplemented serialization hooks - [@dblock](https://github.com/dblock).
|
|
53
|
+
* [#640](https://github.com/hashie/hashie/pull/640): Fixed Dash key transformation skipping hashes inside ordinary Ruby arrays - [@dblock](https://github.com/dblock).
|
|
54
|
+
* [#638](https://github.com/hashie/hashie/pull/638): Fixed Dash and Trash properties named `required?` colliding with required-property validation, following [#276](https://github.com/hashie/hashie/issues/276), reported by [@maxlinc](https://github.com/maxlinc) - [@dblock](https://github.com/dblock).
|
|
55
|
+
* [#616](https://github.com/hashie/hashie/pull/616): Fixed indifferent Trash initialization dropping source keys translated into multiple properties when ignoring undeclared fields, following [#518](https://github.com/hashie/hashie/pull/518) and [#514](https://github.com/hashie/hashie/issues/514) - [@jitendra1998](https://github.com/jitendra1998), [@dblock](https://github.com/dblock).
|
|
56
|
+
* [#609](https://github.com/hashie/hashie/pull/609): Fixed Clash YAML serialization losing stored keys and values, preserving subclasses and parent links - [@dblock](https://github.com/dblock).
|
|
57
|
+
* [#593](https://github.com/hashie/hashie/pull/593): Fix trash subclasses changing superclass transformers - [@complex857](https://github.com/complex857).
|
|
58
|
+
* [#606](https://github.com/hashie/hashie/pull/606): Fix `Hashie::Mash#dup` for subclasses including `MethodAccessWithOverride`, preserving default values and procs - [@Boulea7](https://github.com/Boulea7).
|
|
59
|
+
* [#596](https://github.com/hashie/hashie/pull/596): Fixed `Hashie::Extensions::Mash::DefineAccessors` raising an `ArgumentError` when a Mash key literally matched a suffixed accessor name (e.g. `foo=`, `foo?`, `foo!`, `foo_`) - [@dblock](https://github.com/dblock).
|
|
60
|
+
* [#602](https://github.com/hashie/hashie/pull/602): Fixed `Hashie::Extensions::Coercion`'s `coerce_value` not triggering for nested Hashes inside a `Mash`, since Mash's own recursive Hash-to-Mash conversion ran first - [@dblock](https://github.com/dblock).
|
|
61
|
+
* [#603](https://github.com/hashie/hashie/pull/603): Fixed `Trash`/`PropertyTranslation` incorrectly allowing `:from` to match the property name when the types differ (e.g. a symbol property translated `from:` a string of the same name), causing a "method redefined" warning instead of the intended `ArgumentError` - [@dblock](https://github.com/dblock).
|
|
62
|
+
* [#604](https://github.com/hashie/hashie/pull/604): Fixed `Dash#deep_transform_keys` (and `Trash`) raising `ArgumentError` for required properties under Rails 7+, since `ActiveSupport::Hash#deep_transform_keys` builds its result via `self.class.new` - [@dblock](https://github.com/dblock).
|
|
63
|
+
* [#614](https://github.com/hashie/hashie/pull/614): Fixed `Hashie::Mash#dup` allocating six extra objects on every call since #606, by looking up `Hash#default` and `Hash#default_proc` once and calling them with `bind_call` - [@sampokuokkanen](https://github.com/sampokuokkanen).
|
|
64
|
+
|
|
9
65
|
## [5.1.0] - 2025-12-24
|
|
10
66
|
|
|
11
67
|
[5.1.0]: https://github.com/hashie/hashie/compare/v5.0.0...v5.1.0
|
data/CONTRIBUTING.md
CHANGED
|
@@ -39,6 +39,8 @@ Ensure that you can build the project and run tests.
|
|
|
39
39
|
bundle exec rake
|
|
40
40
|
```
|
|
41
41
|
|
|
42
|
+
CI reports code coverage to Coveralls. Coverage excludes `spec/` and `script/`; their tests and executable examples still run.
|
|
43
|
+
|
|
42
44
|
#### Write Tests
|
|
43
45
|
|
|
44
46
|
Try to write a test that reproduces the problem you're trying to fix or describes a feature that you want to build. Add to [spec/hashie](spec/hashie).
|
|
@@ -49,7 +51,11 @@ We definitely appreciate pull requests that highlight or reproduce a problem, ev
|
|
|
49
51
|
|
|
50
52
|
Implement your feature or bug fix.
|
|
51
53
|
|
|
52
|
-
Ruby style is enforced with [Rubocop](https://github.com/bbatsov/rubocop), run `bundle exec rubocop` and fix any style issues highlighted.
|
|
54
|
+
Ruby style is enforced with [Rubocop](https://github.com/bbatsov/rubocop), run `bundle exec rake rubocop` on Ruby 3.2 or newer and fix any style issues highlighted. Exception messages should start with a lowercase letter and have no trailing punctuation, matching Ruby's built-in exceptions.
|
|
55
|
+
|
|
56
|
+
RuboCop scans Ruby sources, specs, benchmarks, gem manifests, and Ruby scripts across the project, with new cops enabled by default. Ruby files must use `# frozen_string_literal: true`. Existing offenses that cannot be safely corrected are tracked in `.rubocop_todo.yml`.
|
|
57
|
+
|
|
58
|
+
On MRI Ruby 3.2 or newer, RuboCop also checks spelling in Ruby comments and strings and documentation with `rubocop-spellcheck`. The plugin's native dependencies are not installed on JRuby. Fix typos in the source and add intentional project terms to `.spellcheck.txt`, one word per line. Run only the spelling check with `bundle exec rubocop --only Spellcheck/Spelling`. If regenerating vocabulary with `--auto-gen-config`, review the word list so genuine typos are not accepted and preserve the existing `.rubocop_todo.yml` baseline.
|
|
53
59
|
|
|
54
60
|
Make sure that `bundle exec rake` completes without errors.
|
|
55
61
|
|
|
@@ -57,6 +63,37 @@ Make sure that `bundle exec rake` completes without errors.
|
|
|
57
63
|
|
|
58
64
|
Document any external behavior in the [README](README.md).
|
|
59
65
|
|
|
66
|
+
YARD examples cover every public class, module, and method declared in `lib`, and are executable:
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
bundle exec rake docs:examples
|
|
70
|
+
bundle exec rspec spec/documentation_examples_spec.rb
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
The dedicated documentation CI job runs both commands on Ruby 4.0. Railtie and ActiveSupport integration examples run separately on Ruby 3.3 with the real Rails 7 integration bundle: `BUNDLE_GEMFILE=spec/integration/rails_7/Gemfile bundle exec ruby -Ilib script/test_documentation_examples.rb --rails`. Both runs check coverage for all library files; only execution is partitioned by dependency requirements. Each `@example` must be self-contained: Hashie is loaded automatically, but local variables and class definitions are not shared between examples. Put expected Ruby values in inline, single-line `# =>` comments (or `#=>`); the runner evaluates the expression and compares it to the expected value with RSpec equality assertions. Multiline setup is supported, but standalone result comments and examples without assertions fail rather than passing unchecked. For example:
|
|
74
|
+
|
|
75
|
+
```ruby
|
|
76
|
+
# @example Convert keys without changing a flat hash
|
|
77
|
+
# hash = { name: 'Ruby' }
|
|
78
|
+
# Hashie.stringify_keys(hash) # => { 'name' => 'Ruby' }
|
|
79
|
+
# hash # => { name: 'Ruby' }
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
The runner uses maintained YARD parsing and the existing RSpec dependency, rather than importing #421's old yard-doctest/yardstick/inch/Guard stack. Each public class, module, and method needs its own `@example`; a class-level example does not cover its methods. Private methods and APIs already marked `@private` or `@api private` (including their descendants) do not need examples. Do not mark public APIs private merely to avoid documenting them. All `@example` tags are executed, even on internal APIs.
|
|
83
|
+
|
|
84
|
+
The focused specs verify successful execution, incorrect expected values causing a nonzero exit, missing public API examples failing coverage, and internal APIs not requiring coverage. Empty selections also fail. To test selected files, run `bundle exec ruby -Ilib script/test_documentation_examples.rb path/to/file.rb`; the default selection discovers `lib/**/*.rb`, so new files are included automatically.
|
|
85
|
+
|
|
86
|
+
This follows [@michaelherold's documentation in #421](https://github.com/hashie/hashie/pull/421), including its key-conversion examples, and extends executable coverage across the public API. Publishing and versioned GitHub Pages remain separate work; published documentation remains on [RubyDoc.info](https://www.rubydoc.info/gems/hashie). The original PR remains a reference and should not be closed automatically.
|
|
87
|
+
|
|
88
|
+
Fenced Ruby examples in the README are parsed with Kramdown's GFM parser and executed in the documentation CI job. Install the isolated documentation bundle, which supplies real Rails, ActiveModel, and dry-types dependencies, then run:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
BUNDLE_GEMFILE=spec/documentation/Gemfile bundle install
|
|
92
|
+
bundle exec rake docs:readme
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
The runner executes Ruby without rewriting output comments into assertions. Examples demonstrating exceptions rescue the expected exception explicitly. Each example runs in its own namespace and temporary directory; related snippets share a namespace when preceded by matching `<!-- hashie:example descriptive-name -->` comments. Hashie is loaded automatically; snippets require their other dependencies. Shell, YAML, and other non-Ruby fences are not executed. Only run trusted documentation: this is not a sandbox.
|
|
96
|
+
|
|
60
97
|
#### Update Changelog
|
|
61
98
|
|
|
62
99
|
Add a line to [CHANGELOG](CHANGELOG.md) under *Unreleased*. Make it look like every other line, including your name and link to your Github account.
|