| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
| |
The normal behavior of Dash with respect to property defaults differed
from the behavior of a Dash/Trash with IgnoreUndeclared mixed in. This
is because some situations called the defaults and some did not.
This change normalizes the behavior so that all situations where the
defaults should be used to override unset values behave consistently,
as well as all situations where the default should not override a `nil`
value.
|
|
|
|
|
|
|
| |
Following the conventions in `activesupport` and the semantics of the
`#to_hash` method in Ruby's standard library, the `#to_hash` method for
a hash that has mixed in `IndifferentAccess` will now export the hash as
a normal, not-indifferent hash.
|
| |
|
|
|
|
|
|
|
| |
Extends a Dash with the ability to
accept only predefined values on a property.
#61
|
|\
| |
| |
| | |
Small amendments for Hash#merge with IndifferentAccess
|
| |
| |
| |
| |
| |
| |
| |
| |
| | |
1. Use `indifferent_writer` in `convert!` so that when
`indifferent_writer`, `convert_key` or `indifferent_value` is
overridden in included class, `merge` can use those.
2. `convert!` was calling twice if `other` hash was lacking
indifference. `IndifferentAccess.inject!` already does conversion.
|
|/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This PR suppresses the following warning that `deep_merge` method and
`deep_update` method are defined twice when using Ruby 2.6.0+.
```console
% bundle exec rake
(snip)
/Users/koic/src/github.com/hahie/hashie/lib/hashie/mash.rb:226: warning:
method redefined; discarding old deep_merge
/Users/koic/src/github.com/hahie/hashie/lib/hashie/mash.rb:212: warning:
previous definition of deep_merge was here
/Users/koic/src/github.com/hahie/hashie/lib/hashie/mash.rb:232: warning:
method redefined; discarding old deep_update
/Users/koic/src/github.com/hahie/hashie/lib/hashie/mash.rb:218: warning:
previous definition of deep_update was here
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This PR suppresss the following integer unification warning
for Ruby 2.4.0+
```console
% ruby -v
ruby 2.4.9p362 (2019-10-02 revision 67824) [x86_64-darwin17]
% bundle exec rspec spec/hashie/extensions/deep_merge_spec.rb
Hashie::Extensions::DeepMerge
/Users/koic/src/github.com/hahie/hashie/lib/hashie/utils.rb:38: warning:
constant ::Fixnum is deprecated
/Users/koic/src/github.com/hahie/hashie/lib/hashie/utils.rb:38: warning:
constant ::Bignum is deprecated
```
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This PR suppresses the following `Psych.safe_load` args warn when using
Psych 3.1.0 (Ruby 2.6+).
```console
% bundle exec rake spec
(snip)
/Users/koic/src/github.com/intridea/hashie/lib/hashie/extensions/parsers/yaml_erb_parser.rb:22:
Passing permitted_classes with the 2nd argument of Psych.safe_load is
deprecated. Use keyword argument like Psych.safe_load(yaml,
permitted_classes: ...) instead.
/Users/koic/src/github.com/intridea/hashie/lib/hashie/extensions/parsers/yaml_erb_parser.rb:22:
Passing permitted_symbols with the 3rd argument of Psych.safe_load is
deprecated. Use keyword argument like Psych.safe_load(yaml,
permitted_symbols: ...) instead.
/Users/koic/src/github.com/intridea/hashie/lib/hashie/extensions/parsers/yaml_erb_parser.rb:22:
Passing aliases with the 4th argument of Psych.safe_load is
deprecated. Use keyword argument like Psych.safe_load(yaml, aliases:
...) instead
```
|
|\
| |
| | |
Add a PermissiveRespondTo extension for Mashes
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
By default, Mashes don't state that they respond to unset keys. This
causes unexpected behavior when you try to use a Mash with a
SimpleDelegator.
This new extension allows you create a permissive subclass of Mash that
will be fully compatible with SimpleDelegator and allow you to fully do
thunk-oriented programming with Mashes.
This comes with the trade-off of a ~19KB cache for each of these
subclasses and a ~20% performance penalty on any of those subclasses.
|
|/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The `DeepMerge` extension has two methods of mutating hashes: a
destructive one and a non-destructive one. The `#deep_merge` version
should not mutate the original hash or any hash nested within it. The
`#deep_merge!` version is free to mutate the receiver.
Without deeply duplicating the values contained within the hash, the
invariant of immutability cannot be held for the original hash. In order
to preserve that invariant, we need to introduce a method of deeply
duplicating the hash.
The trick here is that we cannot rely on a simple call to `Object#dup`.
Some classes within the Ruby standard library are not duplicable in
particular versions of Ruby. Newer versions of Ruby allow these classes
to be "duplicated" in a way that returns the original value. These
classes represent value objects, so it is safe to return the original
value ... unless the classes are monkey-patched, but that isn't
something we can protect against.
This implementation does a best-effort to deeply duplicate an entire
hash by relying on these value object classes being able to return
themselves without violating immutability.
|
|\
| |
| | |
Remove references to blacklists and whitelists
|
| | |
|
|/
|
|
|
| |
For accessibility reasons, we should limit our lines to 100 chars max.
https://github.com/slack-ruby/slack-ruby-client/pull/293#discussion_r309472083
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
`Mash.load` uses the Ruby standard library to load Yaml-serialized files
into a Mash. The original implementation used `YAML.load` for this
purpose. However, that method is inherently unsafe so we switched to
using `YAML.safe_load`.
Safely loading Yaml files has many different domain-specific
configuration flags that we did not, by default, expose. This change
introduces the ability to configure the safe loading of Yaml files so
that all types of Yaml can be loaded when necessary using the flags from
the standard library.
This implementation preserves the backwards-compatibility with the prior
implementation so that it should not require updates from users of the
current `Mash.load` behavior. For those who this change affects, we
included upgrading documentation to ease the transition.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This patch adds an extension for Mash that makes it behave like
`OpenStruct`. It reduces overhead of `method_missing?` magic which is a
good thing! It's inspired by the recent @sferik's work on `OpenStruct` —
https://github.com/ruby/ruby/pull/1033.
When using it in `Mash` subclasses it makes them *remember* methods so
then it's more like `ActiveModel` than `OpenStruct` in this case.
To use it like `OpenStruct` one could use this shortcut:
```ruby
{ foo: 1, bar: 2 }.to_mash.with_accessors!
```
Implementation details:
It injects to class an anonymous module that stores accessor method
definitions. This is inspired by `ActiveModel` / `ActiveRecord`. It
allows to override accessors in subclass and call them via `super` if
this is intended.
|
|
|
|
|
|
|
|
|
|
|
| |
Disable Metrics/BlockLength in specs because the length of a block in
the test suite isn't something we want to lint. We want the tests to be
as long as they need to be.
Set an explicit line length metric instead of continually updating this
as we go. Let's pick a max line length that we want to see and stick
with it. This metric should only ever decrease: we don't want to see it
ever increase again.
|
|
|
|
|
|
| |
After the last commit, the code is self-explanatory.
Co-authored-by: Ana María Martínez Gómez <ammartinez@suse.de>
|
|
|
|
|
|
|
|
| |
To check if the type class is a Hash, it is more readable to use `==`
than `<=`. It returns `false`/`true` instead of `nil`/`0`, but this doesn't make
a different when using it in a condition.
Co-authored-by: Ana María Martínez Gómez <ammartinez@suse.de>
|
|
|
|
|
| |
Also, reorganize the test into the existing file and update the
changelog.
|
| |
|
|
|
|
|
|
| |
Trash should be able to copy properties from other properties without
causing a problem. Trash should also, when doing this, not set any
properties that it doesn't define.
|
|
|
|
|
|
|
|
| |
The original implementation of PropertyTranslation was heavily reliant
longer methods that added a lot of cognitive load for understanding what
should be happening at any given point. This refactor gives names for all
of the steps that happen at each step to make it easier to reason about
bugs and additions.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This is a big step forward in our Rubocop setup. I addressed all of the todos
from the current version of Rubocop that made sense to. The only things that
remain are metrics and one cop that relies on the line length metric to work.
I made some judgment calls on disabling a few cops:
1. The `Layout/IndentHeredoc` cop wants you to either use the squiggly heredoc
from Ruby 2.3 or introduce a library. Since we are a low-level library that
is used as a transitive dependency, we cannot introduce another library as a
dependence, so that option is out. Also, we support Rubies back to 2.0
currently, so using the squiggly heredoc isn't an option. Once we remove
support for Rubies older than 2.3, we can switch to the squiggly heredoc cop.
2. The `Naming/FileName` cop was reporting false positives for a few files in
the repository, so I disabled it on those files.
3. The `Style/DoubleNegation` cop reports lints on a few cases where we use
double negation. Given the very generic nature of Hashie, the double-negation
is the easiest, clearest way to express that we want an item to be a Boolean.
I disabled the cop because we exist in the gray area where this makes sense.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Hashie::Extensions::Parsers::YamlErbParser::Pathname)
`Hashie::Mash.load` require `Pathname` since v3.4.5.
see: bbafaded9d
```
irb(main):001:0> require "hashie"
=> true
irb(main):002:0> Hashie::Mash.load("foo.yml")
Traceback (most recent call last):
6: from /opt/rubies/2.6.0-dev/bin/irb:11:in `<main>'
5: from (irb):2
4: from /Users/onaka/.gem/ruby/2.6.0/gems/hashie-3.5.7/lib/hashie/mash.rb:105:in `load'
3: from /Users/onaka/.gem/ruby/2.6.0/gems/hashie-3.5.7/lib/hashie/extensions/parsers/yaml_erb_parser.rb:19:in `perform'
2: from /Users/onaka/.gem/ruby/2.6.0/gems/hashie-3.5.7/lib/hashie/extensions/parsers/yaml_erb_parser.rb:19:in `new'
1: from /Users/onaka/.gem/ruby/2.6.0/gems/hashie-3.5.7/lib/hashie/extensions/parsers/yaml_erb_parser.rb:9:in `initialize'
NameError (uninitialized constant Hashie::Extensions::Parsers::YamlErbParser::Pathname)
irb(main):003:0> require "pathname"
=> true
irb(main):004:0> Hashie::Mash.load("foo.yml")
=> #<Hashie::Mash bar="baz">
```
|
|
|
|
|
|
|
|
| |
During non-destructive merges (i.e. `#merge`), the `IndifferentAccess` mixin was
failing to inject itself into the resulting Hash. This caused a `NoMethodError`
to be thrown when attempting to perform the action.
Now, we properly inject the mixin when necessary so the `#merge` method works.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
One of the behaviors of Mash that we see regularly surprise users is
that Mash stringifies any keys passed into it. This leads to unexpected
lack of synergy between Mash and its cousins (particularly Dash), since
the property DSLs do not handle indifferent key access.
This extension ensures that the original keys are kept inside the Mash's
data structure, at the expense of more costly logic for fetching
information indifferently. I have included a benchmark that compares the
two. The benchmark shows that when you are passing string keys into a
Mash, using this extension will actually be _faster_ than the default
implementation, but that the reverse is true when passing symbol keys.
In #296, I tried to do this universally for all Mashes, which slowed
down the fetching behavior for Mash significantly. I like this attempt
much better because it allows users to opt into the new behavior if they
want it, while still keeping the default implementation as-is.
Fixes #196 by giving the option of keeping the original structure of the
Mash when using it with Dash.
Fixes #246 by giving the option of opting into keeping the original
keys.
Closes #296 by giving a more flexible path forward that doesn't change
the semantics of the main Mash class.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We often have requests to make Mash symbolize keys by default. Since
Hashie is used across so many different version of Ruby, we have been
hesitant to make this behavior the default. However, there are valid use
cases for wanting symbol keys.
To satisfy both the needs of those on older Rubies and the needs of
those who want symbol keys, this extension gives the end-user the
ability to toggle on symbolized keys in their Mash subclasses. By adding
this ability, we can wait to implement the symbol keys as a default for
a while longer.
See #341, #342 for more information. This is a half-measure toward the
implementation of #342 (which makes Mash symbolize keys by default).
|
| |
|
| |
|
| |
|
| |
|
| |
|
|
|
|
| |
IgnoreUndeclared
|
|
|
|
|
|
|
|
|
|
| |
(#365)
* Checking for explicit definition of ActiveSupport::HashWithIndifferentAccess, current code assumes that the presence of ActiveSupport implies that HashWithIndifferentAccess was required
* Correcting typo in CHANGELOG update
* Updating CHANGELOG to log fix to #deep_locate
|
|
|
|
| |
https://github.com/intridea/hashie/issues/331
|
| |
|
| |
|
|
|
|
|
|
| |
Translation from `:symbol` and translation from `'string'` are
different translations. No need in coercion to symbol or some other
coercions.
|
|
|
|
|
|
|
|
|
| |
`HashWithDifferentAccess` wasn't properly setting the indifferent
access when merging in other hashes. This reruns `#convert!` after
calling the superclass implementation of the method, so it preserves
indifferent access on the resulting object.
Fixes #345
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
`Hashie::Extensions::DeepLocate.deep_locate`, when passed a key, did not
take into account indifferent access. This lead to a regression in
v3.4.1 when `Hashie::Extensions::DeepFind` was modified to be backed by
`DeepLocate`.
This change makes the default comparator aware of indifferent access by
inspecting the object that it is called on. It works with both
`ActiveSupport::HashWithIndifferentAccess` and
`Hashie::Extensions::IndifferentAccess`.
Fixes #309
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The documentation about the MethodQuery module spells out the expected
behavior. While the spec suite appeared to be testing the same, the
RSpec matchers were not actually checking the behavior properly. This
lead to a divergence between the expected behavior, as outlined in the
module documentation, and the actual behavior, as tested in the spec
suite.
This is the reason that #299 is happening: the expected behavior is not
the actual behavior. I have included a test for #299 to show that it
works as expected in this branch.
This change makes the spec suite match the behavior in the module
documentation, then modifies the methods to match the documentated
specification.
Lastly, I took the time to clean up the MethodQuery module for two
reasons:
1. The old implementation used Regexps on the stringified
method names, which is unnecessary since we have the wonderful
`String#end_with?` method to check the suffix of a strings.
2. The old logic was difficult to reason through, so I clarified the
intent of the methods by reducing the complexity of the conditionals
and extracting meaningful methods where possible.
|
|
|
|
|
|
|
| |
Extension
- Updated, and enhanced specs
- Improved documentation
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
accessed that does not exist in the hash.
In Python a "Hash" is called a "Dictionary", and ...
> "It is an error to extract a value using a non-existent key."
See: https://docs.python.org/2/tutorial/datastructures.html#dictionaries
EXAMPLE:
class StrictHash < Hash
include Hashie::Extensions::StrictKeyAccess
end
>> hash = StrictHash[foo: "bar"]
=> {:foo=>"bar"}
>> hash[:foo]
=> "bar"
>> hash[:cow]
KeyError: key not found: :cow
|