diff --git a/.github/workflows/ancient.yml b/.github/workflows/ancient.yml index 4b061b2..8771e58 100644 --- a/.github/workflows/ancient.yml +++ b/.github/workflows/ancient.yml @@ -37,26 +37,26 @@ jobs: # Ruby 2.3 - ruby: "ruby-2.3" appraisal: "ruby-2-3" - exec_cmd: "rspec spec/snaky_hash/serializer_spec.rb:13" + exec_cmd: "rake test" gemfile: "Appraisal.root" rubygems: "3.3.27" bundler: "2.3.27" -# # Ruby 2.4 -# - ruby: "ruby-2.4" -# appraisal: "ruby-2-4" -# exec_cmd: "rake test" -# gemfile: "Appraisal.root" -# rubygems: "3.3.27" -# bundler: "2.3.27" -# -# # Ruby 2.5 -# - ruby: "ruby-2.5" -# appraisal: "ruby-2-5" -# exec_cmd: "rake test" -# gemfile: "Appraisal.root" -# rubygems: "3.3.27" -# bundler: "2.3.27" + # Ruby 2.4 + - ruby: "ruby-2.4" + appraisal: "ruby-2-4" + exec_cmd: "rake test" + gemfile: "Appraisal.root" + rubygems: "3.3.27" + bundler: "2.3.27" + + # Ruby 2.5 + - ruby: "ruby-2.5" + appraisal: "ruby-2-5" + exec_cmd: "rake test" + gemfile: "Appraisal.root" + rubygems: "3.3.27" + bundler: "2.3.27" steps: - name: Checkout diff --git a/.rubocop_gradual.lock b/.rubocop_gradual.lock index 4ea5290..9f334d6 100644 --- a/.rubocop_gradual.lock +++ b/.rubocop_gradual.lock @@ -5,8 +5,8 @@ "snaky_hash.gemspec:1781125773": [ [4, 23, 12, "Gemspec/RubyVersionGlobalsUsage: Do not use `RUBY_VERSION` in gemspec file.", 31296028] ], - "spec/shared_contexts/base_hash.rb:829438978": [ - [3, 22, 11, "RSpec/ContextWording: Context description should match /^when\\b/, /^with\\b/, or /^without\\b/.", 3936427458] + "spec/shared_contexts/base_hash.rb:2702242093": [ + [12, 22, 11, "RSpec/ContextWording: Context description should match /^when\\b/, /^with\\b/, or /^without\\b/.", 3936427458] ], "spec/snaky_hash/bad_snake_spec.rb:3931746112": [ [3, 16, 11, "RSpec/DescribeClass: The first argument to describe should be the class or module being tested.", 1577626599] diff --git a/CHANGELOG.md b/CHANGELOG.md index f567bac..6130482 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,10 +7,31 @@ and this project adheres to [Semantic Versioning v2](https://semver.org/spec/v2. ## [Unreleased] ### Added ### Changed -### Fixed +### Deprecated ### Removed +### Fixed +### Security + +## [2.0.3] - 2025-05-23 +- TAG: [v2.0.3][2.0.3t] +- COVERAGE: 100.00% -- 132/132 lines in 7 files +- BRANCH COVERAGE: 100.00% -- 38/38 branches in 7 files +- 100.00% documented +### Added +- `#dump` instance method injected by `extend SnakyHash::Serializer` (@pboling) +- `dump_hash_extensions` - new feature, analogous to `load_hash_extensions` (@pboling) +- `dump_value_extensions` - alternate name for `dump_extensions` (@pboling) +- `load_value_extensions` - alternate name for `load_extensions` (@pboling) +- Clarifying documentation (@pboling) +### Fixed +- [gh4](https://github.com/oauth-xx/snaky_hash/pull/4) - Serializer extensions dump and load empty values properly (@pboling) + - Fixed `dump_extensions`, `load_extensions`, `load_hash_extensions` + - Intended usage is primarily JSON, and oauth2 gem + - OAuth2 spec can have legitimately empty values (e.g. scopes could be empty) + - Previous logic was inherited from design decisions made by `serialized_hashie` gem; doesn't apply here -## [2.0.2] - 2025-05-21 ([tag][2.0.2t]) +## [2.0.2] - 2025-05-21 +- TAG: [v2.0.2][2.0.2t] - COVERAGE: 100.00% -- 119/119 lines in 7 files - BRANCH COVERAGE: 100.00% -- 35/35 branches in 7 files - 100.00% documented @@ -26,7 +47,8 @@ and this project adheres to [Semantic Versioning v2](https://semver.org/spec/v2. - Documentation site at [snaky-hash.galtzo.com](https://snaky-hash.galtzo.com) (@pboling) - 100% documented! (@pboling) -## [2.0.1] - 2022-09-23 ([tag][2.0.1t]) +## [2.0.1] - 2022-09-23 +- TAG: [v2.0.1][2.0.1t] ### Added - Certificate for signing gem releases (@pboling) - Gemspec metadata (@pboling) @@ -36,7 +58,8 @@ and this project adheres to [Semantic Versioning v2](https://semver.org/spec/v2. ### Changed - Gem releases are now cryptographically signed (@pboling) -## [2.0.0] - 2022-08-29 ([tag][2.0.0t]) +## [2.0.0] - 2022-08-29 +- TAG: [v2.0.0][2.0.0t] ### Changed - **BREAKING**: `SnakeHash::Snake` is now a mixin, now with support for symbol or string keys ```ruby @@ -48,18 +71,22 @@ end - `SnakyHash::StringKeyed`: a Hashie::Mash class with snake-cased String keys - `SnakyHash::SymbolKeyed`: a Hashie::Mash class with snake-cased Symbol keys -## [1.0.1] - 2022-08-26 ([tag][1.0.1t]) +## [1.0.1] - 2022-08-26 +- TAG: [v1.0.1][1.0.1t] ### Added - Missing LICENSE.txt file to release ### Removed - Accidentally added bundler dependency (vestige of transpec process) is now removed -## [1.0.0] - 2022-08-26 ([tag][1.0.0t]) +## [1.0.0] - 2022-08-26 +- TAG: [v1.0.0][1.0.0t] ### Added - Initial release -[Unreleased]: https://gitlab.com/oauth-xx/snaky_hash/-/compare/v2.0.2...main -[2.0.21]: https://gitlab.com/oauth-xx/snaky_hash/-/compare/v2.0.1...v2.0.2 +[Unreleased]: https://gitlab.com/oauth-xx/snaky_hash/-/compare/v2.0.3...main +[2.0.3]: https://gitlab.com/oauth-xx/snaky_hash/-/compare/v2.0.2...v2.0.3 +[2.0.3t]: https://gitlab.com/oauth-xx/snaky_hash/-/releases/tag/v2.0.3 +[2.0.2]: https://gitlab.com/oauth-xx/snaky_hash/-/compare/v2.0.1...v2.0.2 [2.0.2t]: https://gitlab.com/oauth-xx/snaky_hash/-/releases/tag/v2.0.2 [2.0.1]: https://gitlab.com/oauth-xx/snaky_hash/-/compare/v2.0.0...v2.0.1 [2.0.1t]: https://gitlab.com/oauth-xx/snaky_hash/-/releases/tag/v2.0.1 diff --git a/Gemfile.lock b/Gemfile.lock index 5545a0c..a44e705 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -23,7 +23,7 @@ GIT PATH remote: . specs: - snaky_hash (2.0.2) + snaky_hash (2.0.3) hashie (>= 0.1.0, < 6) version_gem (>= 1.1.8, < 3) diff --git a/README.md b/README.md index f27bc46..df2bdec 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # 🐍 SnakyHash -[![Version][👽versioni]][👽version] [![License: MIT][📄license-img]][📄license-ref] [![Downloads Rank][👽dl-ranki]][👽dl-rank] [![Open Source Helpers][👽oss-helpi]][👽oss-help] [![Depfu][🔑depfui♻️]][🔑depfu] [![Coveralls Test Coverage][🔑coveralls-img]][🔑coveralls] [![QLTY Test Coverage][🔑qlty-covi♻️]][🔑qlty-cov] [![CI Heads][🚎3-hd-wfi]][🚎3-hd-wf] [![CI Runtime Dependencies @ HEAD][🚎12-crh-wfi]][🚎12-crh-wf] [![CI Current][🚎11-c-wfi]][🚎11-c-wf] [![CI Truffle Ruby][🚎9-t-wfi]][🚎9-t-wf] [![CI JRuby][🚎10-j-wfi]][🚎10-j-wf] [![CI Supported][🚎6-s-wfi]][🚎6-s-wf] [![CI Legacy][🚎4-lg-wfi]][🚎4-lg-wf] [![CI Unsupported][🚎7-us-wfi]][🚎7-us-wf] [![CI Ancient][🚎1-an-wfi]][🚎1-an-wf] [![CI Test Coverage][🚎2-cov-wfi]][🚎2-cov-wf] [![CI Style][🚎5-st-wfi]][🚎5-st-wf] [![CodeQL][🖐codeQL-img]][🖐codeQL] +[![Version][👽versioni]][👽version] [![License: MIT][📄license-img]][📄license-ref] [![Downloads Rank][👽dl-ranki]][👽dl-rank] [![Open Source Helpers][👽oss-helpi]][👽oss-help] [![Depfu][🔑depfui♻️]][🔑depfu] [![Coveralls Test Coverage][🔑coveralls-img]][🔑coveralls] [![QLTY Test Coverage][🔑qlty-covi♻️]][🔑qlty-cov] [![QLTY Maintainability][🔑qlty-mnti♻️]][🔑qlty-mnt] [![CI Heads][🚎3-hd-wfi]][🚎3-hd-wf] [![CI Runtime Dependencies @ HEAD][🚎12-crh-wfi]][🚎12-crh-wf] [![CI Current][🚎11-c-wfi]][🚎11-c-wf] [![CI Truffle Ruby][🚎9-t-wfi]][🚎9-t-wf] [![CI JRuby][🚎10-j-wfi]][🚎10-j-wf] [![CI Supported][🚎6-s-wfi]][🚎6-s-wf] [![CI Legacy][🚎4-lg-wfi]][🚎4-lg-wf] [![CI Unsupported][🚎7-us-wfi]][🚎7-us-wf] [![CI Ancient][🚎1-an-wfi]][🚎1-an-wf] [![CI Test Coverage][🚎2-cov-wfi]][🚎2-cov-wf] [![CI Style][🚎5-st-wfi]][🚎5-st-wf] [![CodeQL][🖐codeQL-img]][🖐codeQL] --- @@ -14,7 +14,7 @@ and provide a nice psuedo-object interface. It can be thought of as a mashup of: * `Rash` (specifically the [`rash_alt`](https://github.com/shishi/rash_alt) flavor), which is a special `Mash`, made popular by the `hashie` gem, and -* `serialized_hashie` [gem by krystal](https://github.com/krystal/serialized-hashie) +* `serialized_hashie` [gem by krystal](https://github.com/krystal/serialized-hashie), rewritten, with some behavior changes Classes that `include SnakyHash::Snake.new` should inherit from `Hashie::Mash`. @@ -46,6 +46,17 @@ SnakyHash::StringKeyed.class_eval do end ``` +or you can create a custom class + +```ruby +class MyHash < Hashie::Mash + include SnakyHash::Snake.new(key_type: :string, serializer: true) + # Which is the same as: + # include SnakyHash::Snake.new(key_type: :string) + # extend SnakyHash::Serializer +end +``` + You can then add serialization extensions as needed. See [serialization](#serialization) and [extensions](#extensions) for more. | Federated [DVCS][💎d-in-dvcs] Repository | Status | Issues | PRs | Wiki | CI | Discussions | @@ -212,71 +223,95 @@ This is also not a bug, though if you need different behavior, there is a soluti You can write your own arbitrary extensions: -* "Hash Load" extensions operate on the hash, and nested hashes +* "Hash Load" extensions operate on the hash and nested hashes * use `::load_hash_extensions.add(:extension_name) { |hash| }` -* "Load" extensions operate on the values, and nested hash's values, if any - * use `::load_extensions.add(:extension_name) { |value| }` -* "Dump" extensions operate on the values, and nested hash's values, if any - * use `::dump_extensions.add(:extension_name) { |value| }` + * since v2.0.2, bugs fixed in v2.0.3 +* "Value Load" extensions operate on the values, and nested hashes' values, if any + * use `::load_value_extensions.add(:extension_name) { |value| }` + * since v2.0.2, bugs fixed in v2.0.3 +* "Hash Dump" extensions operate on the hash and nested hashes + * use `::dump_hash_extensions.add(:extension_name) { |value| }` + * since v2.0.3 +* "Value Dump" extensions operate on the values, and nested hashes' values, if any + * use `::dump_value_extensions.add(:extension_name) { |value| }` + * since v2.0.2, bugs fixed in v2.0.3 #### Example -Let's say I want all integer-like keys, except 0, to be integer keys, -while 0 converts to, and stays, a string forever. +Let's say I want to really smash up my hash and make it more food-like. ```ruby class MyExtSnakedHash < Hashie::Mash include SnakyHash::Snake.new( key_type: :symbol, # default :string - serializer: true, # default: false + serializer: true, # default: false ) end -MyExtSnakedHash.load_hash_extensions.add(:non_zero_keys_to_int) do |value| - if value.is_a?(Hash) - value.transform_keys do |key| - key_int = key.to_s.to_i - if key_int > 0 - key_int - else - key - end - end - else - value +# We could swap all values with indexed apples (obliteraating nested data!) +MyExtSnakedHash.dump_hash_extensions.add(:to_apple) do |value| + num = 0 + value.transform_values do |_key| + key = "apple-#{num}" + num += 1 + key end end -snake = MyExtSnakedHash.new(1 => "a", 0 => 4, "VeryFineHat" => {3 => "v", 5 => 7, :very_fine_hat => "feathers"}) # => {1 => "a", 0 => 4, very_fine_hat: {3 => "v", 5 => 7, very_fine_hat: "feathers"}} -dump = MyExtSnakedHash.dump(snake) # => "{\"1\":\"a\",\"0\":4,\"very_fine_hat\":{\"3\":\"v\",\"5\":7,\"very_fine_hat\":\"feathers\"}}" -hydrated = MyExtSnakedHash.load(dump) # => {1 => "a", "0": 4, very_fine_hat: {3 => "v", 5 => 7, very_fine_hat: "feathers"}} -hydrated.class # => MyExtSnakedHash -hydrated["1"] # => nil -hydrated[1] # => "a" -hydrated["0"] # => 4 -hydrated[0] # => nil -hydrated.very_fine_hat # => {3 => "v", 5 => 7, very_fine_hat: "feathers"} -hydrated.very_fine_hat.very_fine_hat # => "feathers" -hydrated.very_fine_hat[:very_fine_hat] # => 'feathers' -hydrated.very_fine_hat["very_fine_hat"] # => 'feathers' +# And then when loading the dump we could convert the yum to pear +MyExtSnakedHash.load_hash_extensions.add(:apple_to_pear) do |value| + value.transform_keys do |key| + key.to_s.sub("yum", "pear") + end +end + +# We could swap all index numbers "beet-" +MyExtSnakedHash.dump_value_extensions.add(:to_beet) do |value| + value.to_s.sub(/(\d+)/) { |match| "beet-#{match[0]}" } +end + +# And then when loading the dump we could convert beet to corn +MyExtSnakedHash.load_value_extensions.add(:beet_to_corn) do |value| + value.to_s.sub("beet", "corn") +end + +snake = MyExtSnakedHash.new({"YumBread" => "b", "YumCake" => {"b" => "b"}, "YumBoba" => [1, 2, 3]}) +snake # => {yum_bread: "b", yum_cake: {b: "b"}, yum_boba: [1, 2, 3]} +snake.yum_bread # => "b" +snake.yum_cake # => {b: "b"} +snake.yum_boba # => [1, 2, 3] +dump = snake.dump +dump # => "{\"yum_bread\":\"apple-beet-0\",\"yum_cake\":\"apple-beet-1\",\"yum_boba\":\"apple-beet-2\"}" +hydrated = MyExtSnakedHash.load(dump) +hydrated # => {pear_bread: "apple-corn-0", pear_cake: "apple-corn-1", pear_boba: "apple-corn-2"} ``` See the specs for more examples. -### Stranger Things +### Bad Ideas I don't recommend using these features... but they exist (for now). + +
+ Show me what I should *not* do! + You can still access the original un-snaked camel keys. And through them you can even use un-snaked camel methods. But don't. ```ruby +snake = SnakyHash::StringKeyed["VeryFineHat" => "Feathers"] snake.key?("VeryFineHat") # => true snake["VeryFineHat"] # => 'Feathers' snake.VeryFineHat # => 'Feathers', PLEASE don't do this!!! snake["VeryFineHat"] = "pop" # Please don't do this... you'll get a warning, and it works (for now), but no guarantees. # WARN -- : You are setting a key that conflicts with a built-in method MySnakedHash#VeryFineHat defined in MySnakedHash. This can cause unexpected behavior when accessing the key as a property. You can still access the key via the #[] method. # => "pop" +``` + +Since you are reading this, here's what to do instead. + +```ruby snake.very_fine_hat = "pop" # => 'pop', do this instead!!! snake.very_fine_hat # => 'pop' snake[:very_fine_hat] = "moose" # => 'moose', or do this instead!!! @@ -285,6 +320,8 @@ snake["very_fine_hat"] = "cheese" # => 'cheese', or do this instead!!! snake.very_fine_hat # => 'cheese' ``` +
+ ### 🚀 Release Instructions See [CONTRIBUTING.md][🤝contributing]. @@ -553,7 +590,7 @@ or one of the others at the head of this README. [📌gitmoji]:https://gitmoji.dev [📌gitmoji-img]:https://img.shields.io/badge/gitmoji_commits-%20😜%20😍-34495e.svg?style=flat-square [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ -[🧮kloc-img]: https://img.shields.io/badge/KLOC-0.119-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue +[🧮kloc-img]: https://img.shields.io/badge/KLOC-0.132-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue [🔐security]: SECURITY.md [🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat [📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year diff --git a/REEK b/REEK index fc7da0f..8bfce7e 100644 --- a/REEK +++ b/REEK @@ -2,27 +2,26 @@ spec/snaky_hash/snake_spec.rb -- 1 warning: [4]:IrresponsibleModule: TheSnakedHash has no descriptive comment [https://github.com/troessner/reek/blob/v6.5.0/docs/Irresponsible-Module.md] lib/snaky_hash/extensions.rb -- 1 warning: [11]:InstanceVariableAssumption: SnakyHash::Extensions assumes too much for instance variable '@extensions' [https://github.com/troessner/reek/blob/v6.5.0/docs/Instance-Variable-Assumption.md] -lib/snaky_hash/serializer.rb -- 8 warnings: - [106]:NilCheck: SnakyHash::Serializer#blank? performs a nil-check [https://github.com/troessner/reek/blob/v6.5.0/docs/Nil-Check.md] - [165]:TooManyStatements: SnakyHash::Serializer#load_value has approx 6 statements [https://github.com/troessner/reek/blob/v6.5.0/docs/Too-Many-Statements.md] - [87]:TooManyStatements: SnakyHash::Serializer::BackportedInstanceMethods#transform_values has approx 7 statements [https://github.com/troessner/reek/blob/v6.5.0/docs/Too-Many-Statements.md] - [58]:TooManyStatements: SnakyHash::Serializer::Modulizer#to_extended_mod has approx 7 statements [https://github.com/troessner/reek/blob/v6.5.0/docs/Too-Many-Statements.md] - [128]:UncommunicativeVariableName: SnakyHash::Serializer#dump_hash has the variable name 'v' [https://github.com/troessner/reek/blob/v6.5.0/docs/Uncommunicative-Variable-Name.md] - [145]:UncommunicativeVariableName: SnakyHash::Serializer#dump_value has the variable name 'v' [https://github.com/troessner/reek/blob/v6.5.0/docs/Uncommunicative-Variable-Name.md] - [172]:UncommunicativeVariableName: SnakyHash::Serializer#load_value has the variable name 'v' [https://github.com/troessner/reek/blob/v6.5.0/docs/Uncommunicative-Variable-Name.md] - [105]:UtilityFunction: SnakyHash::Serializer#blank? doesn't depend on instance state (maybe move it to another class?) [https://github.com/troessner/reek/blob/v6.5.0/docs/Utility-Function.md] +lib/snaky_hash/serializer.rb -- 7 warnings: + [132]:NilCheck: SnakyHash::Serializer#blank? performs a nil-check [https://github.com/troessner/reek/blob/v6.5.0/docs/Nil-Check.md] + [180]:TooManyStatements: SnakyHash::Serializer#load_hash has approx 6 statements [https://github.com/troessner/reek/blob/v6.5.0/docs/Too-Many-Statements.md] + [99]:TooManyStatements: SnakyHash::Serializer::BackportedInstanceMethods#transform_values has approx 7 statements [https://github.com/troessner/reek/blob/v6.5.0/docs/Too-Many-Statements.md] + [58]:TooManyStatements: SnakyHash::Serializer::Modulizer#to_extended_mod has approx 13 statements [https://github.com/troessner/reek/blob/v6.5.0/docs/Too-Many-Statements.md] + [170]:UncommunicativeVariableName: SnakyHash::Serializer#dump_value has the variable name 'v' [https://github.com/troessner/reek/blob/v6.5.0/docs/Uncommunicative-Variable-Name.md] + [214]:UncommunicativeVariableName: SnakyHash::Serializer#load_value has the variable name 'v' [https://github.com/troessner/reek/blob/v6.5.0/docs/Uncommunicative-Variable-Name.md] + [131]:UtilityFunction: SnakyHash::Serializer#blank? doesn't depend on instance state (maybe move it to another class?) [https://github.com/troessner/reek/blob/v6.5.0/docs/Utility-Function.md] lib/snaky_hash/snake.rb -- 11 warnings: [30]:BooleanParameter: SnakyHash::Snake#initialize has boolean parameter 'serializer' [https://github.com/troessner/reek/blob/v6.5.0/docs/Boolean-Parameter.md] - [64, 70]:DuplicateMethodCall: SnakyHash::Snake::SnakyModulizer#to_mod calls 'define_method(:convert_key)' 2 times [https://github.com/troessner/reek/blob/v6.5.0/docs/Duplicate-Method-Call.md] - [64, 70]:DuplicateMethodCall: SnakyHash::Snake::SnakyModulizer#to_mod calls 'key.respond_to?(:to_sym)' 2 times [https://github.com/troessner/reek/blob/v6.5.0/docs/Duplicate-Method-Call.md] - [64, 70]:DuplicateMethodCall: SnakyHash::Snake::SnakyModulizer#to_mod calls 'key.to_s' 2 times [https://github.com/troessner/reek/blob/v6.5.0/docs/Duplicate-Method-Call.md] - [82, 86]:DuplicateMethodCall: SnakyHash::Snake::SnakyModulizer#to_mod calls 'self.class' 2 times [https://github.com/troessner/reek/blob/v6.5.0/docs/Duplicate-Method-Call.md] - [64, 70]:DuplicateMethodCall: SnakyHash::Snake::SnakyModulizer#to_mod calls 'underscore_string(key.to_s)' 2 times [https://github.com/troessner/reek/blob/v6.5.0/docs/Duplicate-Method-Call.md] - [83, 85]:DuplicateMethodCall: SnakyHash::Snake::SnakyModulizer#to_mod calls 'val.dup' 2 times [https://github.com/troessner/reek/blob/v6.5.0/docs/Duplicate-Method-Call.md] - [64, 70]:ManualDispatch: SnakyHash::Snake::SnakyModulizer#to_mod manually dispatches method call [https://github.com/troessner/reek/blob/v6.5.0/docs/Manual-Dispatch.md] - [88]:NestedIterators: SnakyHash::Snake::SnakyModulizer#to_mod contains iterators nested 2 deep [https://github.com/troessner/reek/blob/v6.5.0/docs/Nested-Iterators.md] + [69, 75]:DuplicateMethodCall: SnakyHash::Snake::SnakyModulizer#to_mod calls 'define_method(:convert_key)' 2 times [https://github.com/troessner/reek/blob/v6.5.0/docs/Duplicate-Method-Call.md] + [69, 75]:DuplicateMethodCall: SnakyHash::Snake::SnakyModulizer#to_mod calls 'key.respond_to?(:to_sym)' 2 times [https://github.com/troessner/reek/blob/v6.5.0/docs/Duplicate-Method-Call.md] + [69, 75]:DuplicateMethodCall: SnakyHash::Snake::SnakyModulizer#to_mod calls 'key.to_s' 2 times [https://github.com/troessner/reek/blob/v6.5.0/docs/Duplicate-Method-Call.md] + [87, 91]:DuplicateMethodCall: SnakyHash::Snake::SnakyModulizer#to_mod calls 'self.class' 2 times [https://github.com/troessner/reek/blob/v6.5.0/docs/Duplicate-Method-Call.md] + [69, 75]:DuplicateMethodCall: SnakyHash::Snake::SnakyModulizer#to_mod calls 'underscore_string(key.to_s)' 2 times [https://github.com/troessner/reek/blob/v6.5.0/docs/Duplicate-Method-Call.md] + [88, 90]:DuplicateMethodCall: SnakyHash::Snake::SnakyModulizer#to_mod calls 'val.dup' 2 times [https://github.com/troessner/reek/blob/v6.5.0/docs/Duplicate-Method-Call.md] + [69, 75]:ManualDispatch: SnakyHash::Snake::SnakyModulizer#to_mod manually dispatches method call [https://github.com/troessner/reek/blob/v6.5.0/docs/Manual-Dispatch.md] + [93]:NestedIterators: SnakyHash::Snake::SnakyModulizer#to_mod contains iterators nested 2 deep [https://github.com/troessner/reek/blob/v6.5.0/docs/Nested-Iterators.md] [56]:TooManyStatements: SnakyHash::Snake::SnakyModulizer#to_mod has approx 17 statements [https://github.com/troessner/reek/blob/v6.5.0/docs/Too-Many-Statements.md] - [88]:UncommunicativeVariableName: SnakyHash::Snake::SnakyModulizer#to_mod has the variable name 'e' [https://github.com/troessner/reek/blob/v6.5.0/docs/Uncommunicative-Variable-Name.md] + [93]:UncommunicativeVariableName: SnakyHash::Snake::SnakyModulizer#to_mod has the variable name 'e' [https://github.com/troessner/reek/blob/v6.5.0/docs/Uncommunicative-Variable-Name.md] .yard_gfm_support.rb -- 1 warning: [9, 9]:FeatureEnvy: KramdownGfmDocument#initialize refers to 'options' more than self (maybe move it to another class?) [https://github.com/troessner/reek/blob/v6.5.0/docs/Feature-Envy.md] -22 total warnings +21 total warnings diff --git a/doc/SnakyHash.html b/doc/SnakyHash.html index c4b3cab..6c6f65c 100644 --- a/doc/SnakyHash.html +++ b/doc/SnakyHash.html @@ -147,7 +147,7 @@

Usage with symbol keys and seri

diff --git a/doc/SnakyHash/Error.html b/doc/SnakyHash/Error.html index 2bc57b3..01e250e 100644 --- a/doc/SnakyHash/Error.html +++ b/doc/SnakyHash/Error.html @@ -124,7 +124,7 @@

Overview

diff --git a/doc/SnakyHash/Extensions.html b/doc/SnakyHash/Extensions.html index afa52f4..d2cc5b1 100644 --- a/doc/SnakyHash/Extensions.html +++ b/doc/SnakyHash/Extensions.html @@ -645,7 +645,7 @@

diff --git a/doc/SnakyHash/Serializer.html b/doc/SnakyHash/Serializer.html index af49581..743534a 100644 --- a/doc/SnakyHash/Serializer.html +++ b/doc/SnakyHash/Serializer.html @@ -112,7 +112,7 @@

Basic usage

- Modules: BackportedInstanceMethods, Modulizer + Modules: BackportedInstanceMethods, ConvenienceInstanceMethods, Modulizer @@ -273,7 +273,8 @@

27 28 29 -30 +30 +31
# File 'lib/snaky_hash/serializer.rb', line 21
@@ -281,6 +282,7 @@ 

def extended(base) extended_module = Modulizer.to_extended_mod base.extend(extended_module) + base.include(ConvenienceInstanceMethods) # :nocov: # This will be run in CI on Ruby 2.3, but we only collect coverage from current Ruby unless base.instance_methods.include?(:transform_values) @@ -360,13 +362,13 @@

 
 
-37
 38
 39
-40
+40 +41

-
# File 'lib/snaky_hash/serializer.rb', line 37
+      
# File 'lib/snaky_hash/serializer.rb', line 38
 
 def dump(obj)
   hash = dump_hash(obj)
@@ -438,19 +440,17 @@ 

 
 
-46
 47
 48
 49
 50
-
# File 'lib/snaky_hash/serializer.rb', line 46
+      
# File 'lib/snaky_hash/serializer.rb', line 47
 
 def load(raw_hash)
   hash = JSON.parse(presence(raw_hash) || "{}")
-  hash = load_value(new(hash))
-  new(hash)
+  load_hash(new(hash))
 end
@@ -462,7 +462,7 @@

diff --git a/doc/SnakyHash/Serializer/BackportedInstanceMethods.html b/doc/SnakyHash/Serializer/BackportedInstanceMethods.html index 986d9f6..d461e5b 100644 --- a/doc/SnakyHash/Serializer/BackportedInstanceMethods.html +++ b/doc/SnakyHash/Serializer/BackportedInstanceMethods.html @@ -222,18 +222,18 @@

 
 
-87
-88
-89
-90
-91
-92
-93
-94
-95
+99 +100 +101 +102 +103 +104 +105 +106 +107 -
# File 'lib/snaky_hash/serializer.rb', line 87
+      
# File 'lib/snaky_hash/serializer.rb', line 99
 
 def transform_values(&block)
   return enum_for(:transform_values) { size } unless block_given?
@@ -254,7 +254,7 @@ 

diff --git a/doc/SnakyHash/Serializer/ConvenienceInstanceMethods.html b/doc/SnakyHash/Serializer/ConvenienceInstanceMethods.html new file mode 100644 index 0000000..5557eec --- /dev/null +++ b/doc/SnakyHash/Serializer/ConvenienceInstanceMethods.html @@ -0,0 +1,224 @@ + + + + + + + Module: SnakyHash::Serializer::ConvenienceInstanceMethods + + — Documentation by YARD 0.9.37 + + + + + + + + + + + + + + + + + + + +
+ + +

Module: SnakyHash::Serializer::ConvenienceInstanceMethods + + + +

+
+ + + + + + + + + + + +
+
Defined in:
+
lib/snaky_hash/serializer.rb
+
+ +
+ +

Overview

+
+

Provides convenient instance methods for serialization

+ + +
+
+
+ +
+

Examples:

+ + +

Using convenience methods

+
+ +
hash = MyHash.new(key: 'value')
+json = hash.dump #=> '{"key":"value"}'
+ +
+ + +
+ + + + + + + +

+ Instance Method Summary + collapse +

+ +
    + +
  • + + + #dump ⇒ String + + + + + + + + + + + + + +

    Serializes the current hash instance to JSON.

    +
    + +
  • + + +
+ + + + +
+

Instance Method Details

+ + +
+

+ + #dumpString + + + + + +

+
+

Serializes the current hash instance to JSON

+ + +
+
+
+ +

Returns:

+
    + +
  • + + + (String) + + + + — +

    JSON string representation of the hash

    +
    + +
  • + +
+ +
+ + + + +
+
+
+
+120
+121
+122
+
+
# File 'lib/snaky_hash/serializer.rb', line 120
+
+def dump
+  self.class.dump(self)
+end
+
+
+ +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/doc/SnakyHash/Serializer/Modulizer.html b/doc/SnakyHash/Serializer/Modulizer.html index 9059f77..cb47788 100644 --- a/doc/SnakyHash/Serializer/Modulizer.html +++ b/doc/SnakyHash/Serializer/Modulizer.html @@ -196,24 +196,48 @@

69 70 71 -72

+72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84
# File 'lib/snaky_hash/serializer.rb', line 58
 
 def to_extended_mod
   Module.new do
+    define_method :load_value_extensions do
+      @load_value_extensions ||= Extensions.new
+    end
+
     define_method :load_extensions do
-      @load_extensions ||= Extensions.new
+      load_value_extensions
+    end
+
+    define_method :dump_value_extensions do
+      @dump_value_extensions ||= Extensions.new
     end
 
     define_method :dump_extensions do
-      @dump_extensions ||= Extensions.new
+      dump_value_extensions
     end
 
     define_method :load_hash_extensions do
       @load_hash_extensions ||= Extensions.new
     end
+
+    define_method :dump_hash_extensions do
+      @dump_hash_extensions ||= Extensions.new
+    end
   end
 end
@@ -226,7 +250,7 @@

diff --git a/doc/SnakyHash/Snake.html b/doc/SnakyHash/Snake.html index bbcfefb..d1c3fb6 100644 --- a/doc/SnakyHash/Snake.html +++ b/doc/SnakyHash/Snake.html @@ -376,7 +376,7 @@

diff --git a/doc/SnakyHash/Snake/SnakyModulizer.html b/doc/SnakyHash/Snake/SnakyModulizer.html index c302b5b..2ea2ecf 100644 --- a/doc/SnakyHash/Snake/SnakyModulizer.html +++ b/doc/SnakyHash/Snake/SnakyModulizer.html @@ -358,7 +358,7 @@

diff --git a/doc/SnakyHash/StringKeyed.html b/doc/SnakyHash/StringKeyed.html index 2c29b30..d8835c1 100644 --- a/doc/SnakyHash/StringKeyed.html +++ b/doc/SnakyHash/StringKeyed.html @@ -130,7 +130,7 @@

Overview

diff --git a/doc/SnakyHash/SymbolKeyed.html b/doc/SnakyHash/SymbolKeyed.html index 1ec2c92..8a72f5a 100644 --- a/doc/SnakyHash/SymbolKeyed.html +++ b/doc/SnakyHash/SymbolKeyed.html @@ -130,7 +130,7 @@

Overview

diff --git a/doc/SnakyHash/Version.html b/doc/SnakyHash/Version.html index 5f121a0..c4271d4 100644 --- a/doc/SnakyHash/Version.html +++ b/doc/SnakyHash/Version.html @@ -132,7 +132,7 @@

-
"2.0.2"
+
"2.0.3"
@@ -148,7 +148,7 @@

diff --git a/doc/_index.html b/doc/_index.html index 007b704..14a5542 100644 --- a/doc/_index.html +++ b/doc/_index.html @@ -106,6 +106,21 @@

Namespace Listing A-Z

+ + +