Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Freezing the hash is beneficial at this point because it saves repeated expensive computation if that hash is to be used later in performance-sensitive situations, such as when serving as a cache key or similar.
The reason we do this here is because Dry::Equalizer's hash implementation is always dynamic, i.e. it will recompute the hash every time from the config's full
values
. Dry::Equalizer does provide animmutable: true
option to memoize the hash, but we can't use that forConfig
because it is intended to be mutable for much of its lifecycle.However, there is one point in
Config
's lifecycle at which we know its values should no longer change, which is#finalize!
. By using this as an opportunity to memoize the hash, it will allow users that rely on this hash to trust that it can be used in more performance sensitive situations, such as using it as a cache key.In terms of testing this, I've brought in rspec-benchmarks and added a test to verify that
#hash
on a finalized config is significantly faster than on a non-finalized config:This test does take around 300ms to run, but it is the best way I could think of to exercise this behaviour (e.g. it's much more meaningful IMO than simply asserting that a
@__hash__
ivar exists).Sidenote: config being used as a hash key is what actually happens in dry-view/hanami-view, and this PR is an effort to make dry-configurable more useful in those situations. See dry-rb/dry-view#156 as an effort to work around the issue directly inside dry-view. My preferred approach to solve this for dry-view would be to bring the hash memoizing into dry-configurable, where it can be more appropriately managed alongside the rest of the
Config
logic, and then in dry-view, automatically finalise theconfig
the first time a view instance is initialised.