nina 0.1.2 → 0.1.5

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
  SHA256:
3
- metadata.gz: 28d86e0716c73ae59b0b6ac85076436ae54d1856d072e11114c576cd0b66365e
4
- data.tar.gz: 255f6b2b4ac6b2a6f56f0cbea4fdf38e991494c855cd373417ec99f95af174ac
3
+ metadata.gz: 6a252130b2ce26b317359fa4566edf12fba94042ddb9863fc8c71148a283c718
4
+ data.tar.gz: bb24fa2d53ef3ba45b921cc7a2af366b9e54cd2703681f0cd14210362fe5b473
5
5
  SHA512:
6
- metadata.gz: 745f85388243699c7a2143c8849039b46aad9e343bf3ec005d3f04025d21d4860a7e43969ce06a3ab0357d865bfc4a4efd9fc14c550f551b4aa455a0aa33ab38
7
- data.tar.gz: 6e1a5d9e21e28c3667a56e96b85c1e7c2e6a304ea377d607f1bc1b4b161af4a1e314f4dc28752c2ccc31e982b6cb9b3b0dbf077573dc02c4cd34376baaf4ef75
6
+ metadata.gz: fb97e0c1d28b7dc902366368f770dc3ed7c6f677dd98260dac0caa0a97c16a5d89a09ece6bac74125f7f3a266f4a98baa7a14ff72d163e331b1aa2cb206b0a25
7
+ data.tar.gz: fb26ae5dfac451918af68b16b3f45081559e2e546338fdf8eb0a4b48dcee0f79d4314b3d670b65ac066a472c96ae8c579686ae8f562546a71c2dc81d0bd43f99
data/Gemfile.lock CHANGED
@@ -1,8 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- nina (0.1.2)
5
- toritori (= 0.1.0)
4
+ nina (0.1.5)
5
+ toritori (= 0.2.1)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
@@ -58,7 +58,7 @@ GEM
58
58
  json (>= 1.8, < 3)
59
59
  simplecov-html (~> 0.10.0)
60
60
  simplecov-html (0.10.2)
61
- toritori (0.1.0)
61
+ toritori (0.2.1)
62
62
  unicode-display_width (2.4.2)
63
63
 
64
64
  PLATFORMS
@@ -1,49 +1,43 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'nina/builder/initialization'
4
+ require 'nina/builder/callbacks'
5
+
3
6
  module Nina
4
7
  # Generates module that adds support for objects creation
5
8
  class Assembler
6
- # Adds ability to delegeate methods via method_missing
7
- module MethodMissingDelegation
8
- def method_missing(name, *attrs, &block)
9
- return super unless methods.detect { |m| m == :__predecessor }
10
-
11
- public_send(__predecessor).public_send(name, *attrs, &block)
12
- end
13
-
14
- def respond_to_missing?(method_name, _include_private = false)
15
- return super unless methods.detect { |m| m == :__predecessor }
16
-
17
- public_send(__predecessor).respond_to?(method_name)
18
- end
19
- end
9
+ include Observable
20
10
 
21
- def self.def_accessor(accessor, on:, to:, delegate: false)
22
- on.define_singleton_method(:__predecessor) { accessor }
23
- on.define_singleton_method(accessor) { to }
24
- on.extend(MethodMissingDelegation) if delegate
25
- end
11
+ attr_reader :initialization, :callbacks
26
12
 
27
- def initialize(abstract_factory)
13
+ def initialize(abstract_factory, callbacks = nil)
28
14
  @abstract_factory = abstract_factory
15
+ @initialization = Builder::Initialization.new(@abstract_factory.build_order_list)
16
+ @callbacks = callbacks&.copy || Builder::Callbacks.new(@abstract_factory.build_order_list)
29
17
  end
30
18
 
31
- def inject(build_order, initialization = {}, callbacks: nil, delegate: false)
19
+ def inject(build_order, delegate: false)
32
20
  build_order.each.with_index(-1).inject(nil) do |prev, (name, idx)|
33
21
  object = create_object(name, initialization)
34
- self.class.def_accessor(build_order[idx], on: object, to: prev, delegate: delegate) if prev
35
- callbacks.to_h.fetch(name, []).each { |c| c.call(object) } if callbacks
22
+ setup_relation(object, prev, name, build_order[idx], delegate)
23
+ changed
24
+ notify_observers(name, object)
36
25
  object
37
26
  end
38
27
  end
39
28
 
40
29
  private
41
30
 
31
+ def setup_relation(object, prev, name, accessor, delegate)
32
+ Nina.def_accessor(accessor, on: object, to: prev, delegate: delegate) if prev
33
+ callbacks.to_h[name].each { |c| c.call(object) } if callbacks&.to_h&.key?(name)
34
+ end
35
+
42
36
  def create_object(name, initialization = {})
43
- return @abstract_factory.send("#{name}_factory").create if initialization[name].nil?
37
+ return @abstract_factory.create(name) if initialization.to_h[name].nil?
44
38
 
45
- args, kwargs, block = initialization[name]
46
- @abstract_factory.send("#{name}_factory").create(*args, **kwargs, &block)
39
+ args, kwargs, block = initialization.to_h[name]
40
+ @abstract_factory.create(name, *args, **kwargs, &block)
47
41
  end
48
42
  end
49
43
  end
data/lib/nina/builder.rb CHANGED
@@ -1,8 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'nina/builder/initialization'
4
- require 'nina/builder/callbacks'
5
-
6
3
  # This should be a kind of factory that creates complex objects
7
4
  # from simple ones. It should use torirori to create objects.
8
5
  # It also enriches objects with some methods that make them more
@@ -31,8 +28,7 @@ module Nina
31
28
  build_order_list << name
32
29
  super
33
30
  define_singleton_method(name) do |klass = nil, &definition|
34
- factories[__method__].subclass.base_class(klass) if klass
35
- factories[__method__].subclass(&definition) if definition
31
+ factories[__method__].subclass(produces: klass, &definition)
36
32
  end
37
33
  end
38
34
  end
@@ -43,42 +39,37 @@ module Nina
43
39
  @abstract_factory = abstract_factory.include(Toritori).extend(ClassMethods)
44
40
  @abstract_factory.class_eval(&def_block) if def_block
45
41
  @abstract_factory.build_order_list.freeze
46
- @initialization = Initialization.new(@abstract_factory.factories.keys)
47
- @assembler = Assembler.new(@abstract_factory)
48
- @callbacks = callbacks
42
+ @assembler = Assembler.new(@abstract_factory, callbacks)
43
+ @assembler.add_observer(self)
44
+ @observers = []
45
+ end
46
+
47
+ def add_observer(observer)
48
+ @observers << observer
49
49
  end
50
50
 
51
51
  def copy
52
- self.class.new(name, abstract_factory: abstract_factory)
52
+ new_builder = self.class.new(name, abstract_factory: abstract_factory, callbacks: @assembler.callbacks)
53
+ @observers.each { |observer| new_builder.add_observer(observer) }
54
+ new_builder
53
55
  end
54
56
 
55
57
  def with_callbacks(&block)
56
- c = callbacks&.copy || Callbacks.new(abstract_factory.factories.keys)
57
- yield c if block
58
+ yield @assembler.callbacks if block
58
59
 
59
- self.class.new(name, abstract_factory: abstract_factory, callbacks: c)
60
+ copy
60
61
  end
61
62
 
62
63
  def wrap(delegate: false, &block)
63
- yield @initialization if block
64
-
65
- @assembler.inject(
66
- @abstract_factory.build_order_list,
67
- @initialization.to_h,
68
- callbacks: callbacks,
69
- delegate: delegate
70
- )
64
+ yield @assembler.initialization if block
65
+
66
+ @assembler.inject(@abstract_factory.build_order_list, delegate: delegate)
71
67
  end
72
68
 
73
69
  def nest(delegate: false, &block)
74
- yield @initialization if block
75
-
76
- @assembler.inject(
77
- @abstract_factory.build_order_list.reverse,
78
- @initialization.to_h,
79
- callbacks: callbacks,
80
- delegate: delegate
81
- )
70
+ yield @assembler.initialization if block
71
+
72
+ @assembler.inject(@abstract_factory.build_order_list.reverse, delegate: delegate)
82
73
  end
83
74
 
84
75
  def subclass(&def_block)
@@ -87,8 +78,13 @@ module Nina
87
78
  @abstract_factory = Class.new(abstract_factory)
88
79
  @abstract_factory.class_eval(&def_block)
89
80
  @abstract_factory.build_order_list.freeze
90
- @initialization = Initialization.new(@abstract_factory.factories.keys)
91
- @assembler = Assembler.new(@abstract_factory)
81
+ @assembler = Assembler.new(@abstract_factory, @assembler.callbacks)
82
+ end
83
+
84
+ def update(name, object)
85
+ @observers.each do |observer|
86
+ observer.public_send(:"on_#{name}_created", object) if observer.respond_to?(:"on_#{name}_created")
87
+ end
92
88
  end
93
89
  end
94
90
  end
data/lib/nina/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Nina
4
- VERSION = '0.1.2'
4
+ VERSION = '0.1.5'
5
5
  end
data/lib/nina.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'toritori'
4
+ require 'observer'
4
5
  require 'nina/assembler'
5
6
  require 'nina/builder'
6
7
 
@@ -31,7 +32,45 @@ module Nina
31
32
  end
32
33
  end
33
34
 
35
+ # Adds ability to delegeate methods via method_missing
36
+ module MethodMissingDelegation
37
+ def method_missing(name, *attrs, **kwargs, &block)
38
+ if (prev = predecessors.lazy.detect { |o| o.public_methods.include?(name) })
39
+ prev.public_send(name, *attrs, **kwargs, &block)
40
+ else
41
+ super
42
+ end
43
+ end
44
+
45
+ def respond_to_missing?(method_name, _include_private = false)
46
+ public_methods.detect { |m| m == :predecessor } || super
47
+ end
48
+
49
+ def predecessors
50
+ Enumerator.new do |y|
51
+ obj = self
52
+ y << obj = obj.predecessor while obj.methods.detect { |m| m == :predecessor }
53
+ end
54
+ end
55
+ end
56
+
34
57
  def self.included(receiver)
35
58
  receiver.extend ClassMethods
36
59
  end
60
+
61
+ def self.def_accessor(accessor, on:, to:, delegate: false)
62
+ on.define_singleton_method(accessor) { to }
63
+ on.define_singleton_method(:predecessor) { to }
64
+ return unless delegate
65
+
66
+ on.extend(MethodMissingDelegation)
67
+ end
68
+
69
+ def self.linked_list(build_config, delegate: false)
70
+ build_order = build_config.keys
71
+ build_config.each.with_index(-1).inject(nil) do |prev, ((_, object), idx)|
72
+ Nina.def_accessor(build_order[idx], on: object, to: prev, delegate: delegate) if prev
73
+ object
74
+ end
75
+ end
37
76
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nina
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrii Baran
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-07-12 00:00:00.000000000 Z
11
+ date: 2024-01-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: toritori
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 0.1.0
19
+ version: 0.2.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 0.1.0
26
+ version: 0.2.1
27
27
  description: Reduce biolerplate code when you need to create complex OOD composition
28
28
  email:
29
29
  - andriy.baran.v@gmail.com