dry-initializer 0.2.0 → 0.2.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a155e17b7e2f0fb9274bf3b6511c64380784ae90
4
- data.tar.gz: 967ba81a147fa585ba889b3e97378a3340db312a
3
+ metadata.gz: 6a766e40753a382067be26c74413c5559153aa5c
4
+ data.tar.gz: c42a2c954be3312dd1c319afa9cbd8c27f3651b3
5
5
  SHA512:
6
- metadata.gz: af677c57dc5ca40e7c2d3540cb566e145643daecf2eb564c752f95b3123f74bfed8320edecf9764cb933cd007ee7421728e1965941f122187dcdbd7ff0b830bd
7
- data.tar.gz: 7d8d21a38ff8a0cb08a41ee8e3c37665a020a1314bb59851f3c85d3eff58b96196a105c8a32c8f9b46bb8961f5c2681122c578fe6a01d481d270d02a2a956944
6
+ metadata.gz: c8825deefcd6da06a075b83a17fbcbafcbd0f5d4887330567b71df464979970aae455b7c9c9f4bb40a34abddfa4ffde89553712f1a2b81de249ea24009511e0a
7
+ data.tar.gz: 31c7ec0f9c6b582967438cf0feb8bb270e5ac6c9028d4e587f4c68a6b5980ba6ccfde630555f9295af90477003cb49988048e2f23a7644a383bf83efcff5be11
data/.travis.yml CHANGED
@@ -8,9 +8,9 @@ rvm:
8
8
  - '2.3.0'
9
9
  - rbx-2
10
10
  - ruby-head
11
- # - jruby-9
12
- # - jruby-head
11
+ - jruby-9
12
+ - jruby-head
13
13
  matrix:
14
14
  allow_failures:
15
15
  - rvm: ruby-head
16
- # - rvm: jruby-head
16
+ - rvm: jruby-head
data/CHANGELOG.md CHANGED
@@ -1,4 +1,18 @@
1
- ## v0.2.0 2016-04-28
1
+ ## v0.2.1 2016-05-19
2
+
3
+ ### Bugs Fixed
4
+
5
+ * Fix polluting superclass with declarations from subclass (@nepalez)
6
+
7
+ ### Internals
8
+
9
+ * Make all instances (Builder and Signature) immutable (@nepalez)
10
+ * Decouple mixin from a builder to prevent pollution (@nepalez)
11
+ * Ensure default value block can use private variables (@jeremyf)
12
+
13
+ [Compare v0.2.0...v0.2.1](https://github.com/dry-rb/dry-initializer/compare/v0.2.0...v0.2.1)
14
+
15
+ ## v0.2.0 2016-05-16
2
16
 
3
17
  The gem internals has been rewritten heavily to make the gem pluggable and fix
4
18
  bugs in "container style". Type constraints were extracted to a plugin
data/Gemfile CHANGED
@@ -3,8 +3,6 @@ source "https://rubygems.org"
3
3
  # Specify your gem"s dependencies in dry-initializer.gemspec
4
4
  gemspec
5
5
 
6
- gem "dry-types", git: "https://github.com/dryrb/dry-types", branch: "master"
7
-
8
6
  group :benchmarks do
9
7
  gem "benchmark-ips", "~> 2.5"
10
8
 
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |gem|
2
2
  gem.name = "dry-initializer"
3
- gem.version = "0.2.0"
3
+ gem.version = "0.2.1"
4
4
  gem.author = ["Vladimir Kochnev (marshall-lee)", "Andrew Kozin (nepalez)"]
5
5
  gem.email = ["hashtable@yandex.ru", "andrew.kozin@gmail.com"]
6
6
  gem.homepage = "https://github.com/dryrb/dry-initializer"
@@ -15,5 +15,5 @@ Gem::Specification.new do |gem|
15
15
 
16
16
  gem.add_development_dependency "rspec", "~> 3.0"
17
17
  gem.add_development_dependency "rake", "~> 10.0"
18
- gem.add_development_dependency "dry-types", "~> 0.5.1"
18
+ gem.add_development_dependency "dry-types", "~> 0.5", "> 0.5.1"
19
19
  end
@@ -18,51 +18,46 @@ module Dry::Initializer
18
18
  # @param [Dry::Initializer::Plugin]
19
19
  #
20
20
  def register(plugin)
21
- @plugins << plugin
21
+ plugins = @plugins + [plugin]
22
+ copy { @plugins = plugins }
22
23
  end
23
24
 
24
- # Defines new agrument and rebuilds the initializer
25
+ # Defines new agrument and reloads mixin definitions
25
26
  #
27
+ # @param [Module] mixin
26
28
  # @param [#to_sym] name
27
29
  # @param [Hash<Symbol, Object>] settings
28
30
  #
29
31
  # @return [self] itself
30
32
  #
31
- def define(name, settings)
32
- update_signature(name, settings)
33
- update_parts(name, settings)
33
+ def reload(mixin, name, settings)
34
+ signature = @signature.add(name, settings)
35
+ parts = @parts + @plugins.map { |p| p.call(name, settings) }.compact
34
36
 
35
- define_reader(name, settings)
36
- reload_initializer
37
- reload_callback
37
+ copy do
38
+ @signature = signature
39
+ @parts = parts
38
40
 
39
- self
40
- end
41
-
42
- # The module with two methods: `#initialize` and `##__after_initialize__`
43
- # to be mixed into the target class
44
- #
45
- # @return [Module]
46
- #
47
- def mixin
48
- @mixin ||= Module.new
41
+ define_readers(mixin)
42
+ reload_initializer(mixin)
43
+ reload_callback(mixin)
44
+ end
49
45
  end
50
46
 
51
47
  private
52
48
 
53
- def update_signature(name, settings)
54
- @signature.add(name, settings)
49
+ def copy(&block)
50
+ dup.tap { |instance| instance.instance_eval(&block) }
55
51
  end
56
52
 
57
- def update_parts(name, settings)
58
- @parts += @plugins.map { |klass| klass.call(name, settings) }.compact
59
- end
53
+ def define_readers(mixin)
54
+ readers = @signature.select { |item| item.settings[:reader] != false }
55
+ .map(&:name)
60
56
 
61
- def define_reader(name, settings)
62
- mixin.send :attr_reader, name unless settings[:reader] == false
57
+ mixin.send :attr_reader, *readers if readers.any?
63
58
  end
64
59
 
65
- def reload_initializer
60
+ def reload_initializer(mixin)
66
61
  strings = @parts.select { |part| String === part }
67
62
 
68
63
  mixin.class_eval <<-RUBY
@@ -73,7 +68,7 @@ module Dry::Initializer
73
68
  RUBY
74
69
  end
75
70
 
76
- def reload_callback
71
+ def reload_callback(mixin)
77
72
  blocks = @parts.select { |part| Proc === part }
78
73
 
79
74
  mixin.send :define_method, :__after_initialize__ do
@@ -12,7 +12,8 @@ module Dry::Initializer
12
12
  # @return [self] itself
13
13
  #
14
14
  def param(name, **options)
15
- initializer_builder.define(name, option: false, **options)
15
+ @initializer_builder = initializer_builder
16
+ .reload(self, name, option: false, **options)
16
17
  self
17
18
  end
18
19
 
@@ -23,22 +24,19 @@ module Dry::Initializer
23
24
  # @return (see #param)
24
25
  #
25
26
  def option(name, **options)
26
- initializer_builder.define(name, option: true, **options)
27
+ @initializer_builder = initializer_builder
28
+ .reload(self, name, option: true, **options)
27
29
  self
28
30
  end
29
31
 
30
32
  # @private
31
33
  def initializer_builder
32
- @initializer_builder ||= begin
33
- builder = Builder.new
34
- include builder.mixin
35
- builder
36
- end
34
+ @initializer_builder ||= Builder.new
37
35
  end
38
36
 
39
37
  # @private
40
38
  def inherited(klass)
41
- klass.instance_variable_set(:@initializer_builder, initializer_builder)
39
+ klass.instance_variable_set :@initializer_builder, initializer_builder.dup
42
40
  end
43
41
  end
44
42
  end
@@ -1,12 +1,12 @@
1
1
  module Dry::Initializer
2
- # Mutable container for chunks of code describing argument signatures.
2
+ # Immutable container for chunks of code describing argument signatures.
3
3
  # Responcible for building the resulting signature for the initializer args.
4
4
  class Signature
5
5
  include Enumerable
6
6
  include Errors
7
7
 
8
8
  def initialize
9
- @list ||= []
9
+ @list = []
10
10
  end
11
11
 
12
12
  def add(*args)
@@ -15,8 +15,13 @@ module Dry::Initializer
15
15
  validates_uniqueness_of signature
16
16
  validates_order_of signature
17
17
 
18
- @list << signature
19
- self
18
+ copy { @list += [signature] }
19
+ end
20
+
21
+ def each
22
+ (@list.select(&:param?) + @list.reject(&:param?)).each do |item|
23
+ yield item
24
+ end
20
25
  end
21
26
 
22
27
  def call
@@ -25,9 +30,9 @@ module Dry::Initializer
25
30
 
26
31
  private
27
32
 
28
- def each
29
- (@list.select(&:param?) + @list.reject(&:param?)).each do |item|
30
- yield item
33
+ def copy(&block)
34
+ dup.tap do |instance|
35
+ instance.instance_eval(&block)
31
36
  end
32
37
  end
33
38
 
@@ -7,6 +7,13 @@ describe "default values" do
7
7
  param :bar, default: proc { :BAR }
8
8
  option :baz, default: proc { :BAZ }
9
9
  option :qux, default: proc { foo }
10
+ option :mox, default: proc { default_mox }
11
+
12
+ private
13
+
14
+ def default_mox
15
+ :MOX
16
+ end
10
17
  end
11
18
  end
12
19
 
@@ -36,4 +43,9 @@ describe "default values" do
36
43
  expect(subject.baz).to eql 3
37
44
  expect(subject.qux).to eql 1
38
45
  end
46
+
47
+ it "applies default values from private methods" do
48
+ subject = Test::Foo.new
49
+ expect(subject.mox).to eql :MOX
50
+ end
39
51
  end
@@ -8,7 +8,7 @@ describe "object type constraint" do
8
8
  end
9
9
 
10
10
  context "in case of mismatch" do
11
- subject { Test::Foo.new 'baz' }
11
+ subject { Test::Foo.new "baz" }
12
12
 
13
13
  it "raises TypeError" do
14
14
  expect { subject }.to raise_error TypeError
@@ -16,7 +16,7 @@ describe "object type constraint" do
16
16
  end
17
17
 
18
18
  context "in case of match" do
19
- subject { Test::Foo.new 'barbar' }
19
+ subject { Test::Foo.new "barbar" }
20
20
 
21
21
  it "completes the initialization" do
22
22
  expect { subject }.not_to raise_error
@@ -1,5 +1,5 @@
1
1
  describe "subclassing" do
2
- subject do
2
+ before do
3
3
  class Test::Foo
4
4
  extend Dry::Initializer::Mixin
5
5
 
@@ -11,14 +11,25 @@ describe "subclassing" do
11
11
  param :baz
12
12
  option :qux
13
13
  end
14
+ end
15
+
16
+ let(:instance_of_superclass) do
17
+ Test::Foo.new 1, bar: 3
18
+ end
14
19
 
20
+ let(:instance_of_subclass) do
15
21
  Test::Bar.new 1, 2, bar: 3, qux: 4
16
22
  end
17
23
 
18
24
  it "preserves definitions made in the superclass" do
19
- expect(subject.foo).to eql 1
20
- expect(subject.baz).to eql 2
21
- expect(subject.bar).to eql 3
22
- expect(subject.qux).to eql 4
25
+ expect(instance_of_subclass.foo).to eql 1
26
+ expect(instance_of_subclass.baz).to eql 2
27
+ expect(instance_of_subclass.bar).to eql 3
28
+ expect(instance_of_subclass.qux).to eql 4
29
+ end
30
+
31
+ it "does not pollute superclass with definitions from subclass" do
32
+ expect(instance_of_superclass).not_to respond_to :baz
33
+ expect(instance_of_superclass).not_to respond_to :qux
23
34
  end
24
35
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dry-initializer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vladimir Kochnev (marshall-lee)
@@ -9,50 +9,56 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-05-15 00:00:00.000000000 Z
12
+ date: 2016-05-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
+ name: rspec
15
16
  requirement: !ruby/object:Gem::Requirement
16
17
  requirements:
17
18
  - - "~>"
18
19
  - !ruby/object:Gem::Version
19
20
  version: '3.0'
20
21
  type: :development
22
+ prerelease: false
21
23
  version_requirements: !ruby/object:Gem::Requirement
22
24
  requirements:
23
25
  - - "~>"
24
26
  - !ruby/object:Gem::Version
25
27
  version: '3.0'
26
- name: rspec
27
- prerelease: false
28
28
  - !ruby/object:Gem::Dependency
29
+ name: rake
29
30
  requirement: !ruby/object:Gem::Requirement
30
31
  requirements:
31
32
  - - "~>"
32
33
  - !ruby/object:Gem::Version
33
34
  version: '10.0'
34
35
  type: :development
36
+ prerelease: false
35
37
  version_requirements: !ruby/object:Gem::Requirement
36
38
  requirements:
37
39
  - - "~>"
38
40
  - !ruby/object:Gem::Version
39
41
  version: '10.0'
40
- name: rake
41
- prerelease: false
42
42
  - !ruby/object:Gem::Dependency
43
+ name: dry-types
43
44
  requirement: !ruby/object:Gem::Requirement
44
45
  requirements:
45
46
  - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '0.5'
49
+ - - ">"
46
50
  - !ruby/object:Gem::Version
47
51
  version: 0.5.1
48
52
  type: :development
53
+ prerelease: false
49
54
  version_requirements: !ruby/object:Gem::Requirement
50
55
  requirements:
51
56
  - - "~>"
57
+ - !ruby/object:Gem::Version
58
+ version: '0.5'
59
+ - - ">"
52
60
  - !ruby/object:Gem::Version
53
61
  version: 0.5.1
54
- name: dry-types
55
- prerelease: false
56
62
  description:
57
63
  email:
58
64
  - hashtable@yandex.ru
@@ -154,3 +160,4 @@ test_files:
154
160
  - spec/dry/subclassing_spec.rb
155
161
  - spec/dry/value_coercion_via_dry_types_spec.rb
156
162
  - spec/spec_helper.rb
163
+ has_rdoc: