dry-initializer 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
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: