From 1abeec660de3d3c51c6db19664a08f443a650455 Mon Sep 17 00:00:00 2001 From: Nikita Shilnikov Date: Fri, 7 Jun 2019 12:13:09 +0300 Subject: [PATCH] Add Mixin#{dup,clone} (fixes #63) We shoulnt't share `_container` instances across different containers, it leads to bugs and confusion. --- lib/dry/container/mixin.rb | 16 ++++++++++++++++ spec/support/shared_examples/container.rb | 19 +++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/lib/dry/container/mixin.rb b/lib/dry/container/mixin.rb index 1a31b34..590f2b9 100644 --- a/lib/dry/container/mixin.rb +++ b/lib/dry/container/mixin.rb @@ -270,6 +270,22 @@ def freeze def _container @_container end + + # @api public + def dup + copy = super + copy.instance_variable_set(:@_container, _container.dup) + copy + end + + # @api public + def clone + copy = super + unless copy.frozen? + copy.instance_variable_set(:@_container, _container.dup) + end + copy + end end end end diff --git a/spec/support/shared_examples/container.rb b/spec/support/shared_examples/container.rb index 0aa2c35..11194e4 100644 --- a/spec/support/shared_examples/container.rb +++ b/spec/support/shared_examples/container.rb @@ -616,4 +616,23 @@ expect(container.freeze).to be(container) end end + + describe '.dup' do + it "returns a copy that doesn't share registered keys with the parent" do + container.dup.register(:foo, 'bar') + expect(container.key?(:foo)).to be false + end + end + + describe '.clone' do + it "returns a copy that doesn't share registered keys with the parent" do + container.clone.register(:foo, 'bar') + expect(container.key?(:foo)).to be false + end + + it 're-uses frozen container' do + expect(container.freeze.clone).to be_frozen + expect(container.clone._container).to be(container._container) + end + end end