nina 0.1.1 → 0.1.4
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 +4 -4
- data/CHANGELOG.md +5 -0
- data/Gemfile.lock +3 -3
- data/README.md +12 -0
- data/lib/nina/assembler.rb +4 -25
- data/lib/nina/builder/callbacks.rb +24 -0
- data/lib/nina/builder/initialization.rb +29 -0
- data/lib/nina/builder.rb +20 -50
- data/lib/nina/version.rb +1 -1
- data/lib/nina.rb +40 -0
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2fa283d983d2df265fc4d74813c9abefb8f351c2582245d359a497514f4a61a5
|
4
|
+
data.tar.gz: 0e6ee2d867415efdec03f53d35be33a99ad202b4e2aa9f76ab9683b9657af999
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 822d7360687494fefea19be97898eefa121c3aff71ba579d1030730b9a3b97e5409d6fe53990f43f2b175e132ff78a7184c79956e2545647aeaccd1c0a8c8c2a
|
7
|
+
data.tar.gz: fc42924b259b4c68ceca3e14b951ae45aadd61214b8ac7944294a283d183cd5bfedc6b4248287b55364e175ef9bfcb7fbfaad8e5c564a33fcbbc0acd9b851aaf
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
nina (0.1.
|
5
|
-
toritori (= 0.1
|
4
|
+
nina (0.1.4)
|
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
|
61
|
+
toritori (0.2.1)
|
62
62
|
unicode-display_width (2.4.2)
|
63
63
|
|
64
64
|
PLATFORMS
|
data/README.md
CHANGED
@@ -111,6 +111,18 @@ instance.query.b # => 2
|
|
111
111
|
instance.c # => nil
|
112
112
|
```
|
113
113
|
|
114
|
+
We are copying callbacks from builder if had some defined
|
115
|
+
```ruby
|
116
|
+
builder_with_callbacks = builder.with_callbacks do |c|
|
117
|
+
c.params { _1.a = 1 }
|
118
|
+
end
|
119
|
+
builder_with_callbacks_with_callbacks = builder_with_callbacks.with_callbacks do |c|
|
120
|
+
c.params { _1.a += 1 }
|
121
|
+
end
|
122
|
+
instance = builder_with_callbacks.wrap
|
123
|
+
instance.a # => 2
|
124
|
+
```
|
125
|
+
|
114
126
|
## Development
|
115
127
|
|
116
128
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/lib/nina/assembler.rb
CHANGED
@@ -3,27 +3,6 @@
|
|
3
3
|
module Nina
|
4
4
|
# Generates module that adds support for objects creation
|
5
5
|
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
|
20
|
-
|
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
|
26
|
-
|
27
6
|
def initialize(abstract_factory)
|
28
7
|
@abstract_factory = abstract_factory
|
29
8
|
end
|
@@ -31,8 +10,8 @@ module Nina
|
|
31
10
|
def inject(build_order, initialization = {}, callbacks: nil, delegate: false)
|
32
11
|
build_order.each.with_index(-1).inject(nil) do |prev, (name, idx)|
|
33
12
|
object = create_object(name, initialization)
|
34
|
-
|
35
|
-
callbacks
|
13
|
+
Nina.def_accessor(build_order[idx], on: object, to: prev, delegate: delegate) if prev
|
14
|
+
callbacks[name].each { |c| c.call(object) } if callbacks&.key?(name)
|
36
15
|
object
|
37
16
|
end
|
38
17
|
end
|
@@ -40,10 +19,10 @@ module Nina
|
|
40
19
|
private
|
41
20
|
|
42
21
|
def create_object(name, initialization = {})
|
43
|
-
return @abstract_factory.
|
22
|
+
return @abstract_factory.factories[name].create if initialization[name].nil?
|
44
23
|
|
45
24
|
args, kwargs, block = initialization[name]
|
46
|
-
@abstract_factory.
|
25
|
+
@abstract_factory.factories[name].create(*args, **kwargs, &block)
|
47
26
|
end
|
48
27
|
end
|
49
28
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Nina
|
4
|
+
class Builder
|
5
|
+
# Utility to get user defined callbacks
|
6
|
+
class Callbacks < Initialization
|
7
|
+
def copy
|
8
|
+
Callbacks.new(@allow_list, to_h.dup)
|
9
|
+
end
|
10
|
+
|
11
|
+
def method_missing(method, *args, **kwargs, &block)
|
12
|
+
return super unless @allow_list.include?(method)
|
13
|
+
|
14
|
+
@atts[method] unless block
|
15
|
+
@atts[method] ||= []
|
16
|
+
@atts[method] << block
|
17
|
+
end
|
18
|
+
|
19
|
+
def respond_to_missing?(method, include_private = false)
|
20
|
+
super
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Nina
|
4
|
+
class Builder
|
5
|
+
# A way to call methods from initalization proc on base_class
|
6
|
+
class Initialization < BasicObject
|
7
|
+
attr_reader :allow_list
|
8
|
+
|
9
|
+
def initialize(allow_list, atts = {})
|
10
|
+
@allow_list = allow_list
|
11
|
+
@atts = atts
|
12
|
+
end
|
13
|
+
|
14
|
+
def method_missing(method, *args, **kwargs, &block)
|
15
|
+
return super unless @allow_list.include?(method)
|
16
|
+
|
17
|
+
@atts[method] = [args, kwargs, block]
|
18
|
+
end
|
19
|
+
|
20
|
+
def respond_to_missing?(method, include_private = false)
|
21
|
+
@allow_list.include?(method) || super
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_h
|
25
|
+
@atts
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/nina/builder.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'nina/builder/initialization'
|
4
|
+
require 'nina/builder/callbacks'
|
5
|
+
|
3
6
|
# This should be a kind of factory that creates complex objects
|
4
7
|
# from simple ones. It should use torirori to create objects.
|
5
8
|
# It also enriches objects with some methods that make them more
|
@@ -7,41 +10,7 @@
|
|
7
10
|
module Nina
|
8
11
|
# Generates module that adds support for objects creation
|
9
12
|
class Builder
|
10
|
-
attr_reader :name, :abstract_factory, :def_block
|
11
|
-
attr_accessor :callbacks
|
12
|
-
|
13
|
-
# A way to call methods from initalization proc on base_class
|
14
|
-
class Initialization < BasicObject
|
15
|
-
def initialize(list)
|
16
|
-
@list = list
|
17
|
-
@atts = {}
|
18
|
-
end
|
19
|
-
|
20
|
-
def method_missing(method, *args, **kwargs, &block)
|
21
|
-
return super unless @list.include?(method)
|
22
|
-
|
23
|
-
@atts[method] = [args, kwargs, block]
|
24
|
-
end
|
25
|
-
|
26
|
-
def respond_to_missing?(method, include_private = false)
|
27
|
-
@list.include?(method) || super
|
28
|
-
end
|
29
|
-
|
30
|
-
def to_h
|
31
|
-
@atts
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
# Utility to get user defined callbacks
|
36
|
-
class Callbacks < Initialization
|
37
|
-
def method_missing(method, *args, **kwargs, &block)
|
38
|
-
return super unless @list.include?(method)
|
39
|
-
|
40
|
-
@atts[method] unless block
|
41
|
-
@atts[method] ||= []
|
42
|
-
@atts[method] << block
|
43
|
-
end
|
44
|
-
end
|
13
|
+
attr_reader :name, :abstract_factory, :def_block, :callbacks
|
45
14
|
|
46
15
|
# Definaes support methods and variables for concrete builder
|
47
16
|
module ClassMethods
|
@@ -62,23 +31,12 @@ module Nina
|
|
62
31
|
build_order_list << name
|
63
32
|
super
|
64
33
|
define_singleton_method(name) do |klass = nil, &definition|
|
65
|
-
factories[__method__].subclass
|
66
|
-
factories[__method__].subclass(&definition) if definition
|
34
|
+
factories[__method__].subclass(produces: klass, &definition)
|
67
35
|
end
|
68
36
|
end
|
69
37
|
end
|
70
38
|
|
71
|
-
def
|
72
|
-
self.class.new(name, abstract_factory: abstract_factory)
|
73
|
-
end
|
74
|
-
|
75
|
-
def with_callbacks(&block)
|
76
|
-
yield c = Callbacks.new(abstract_factory.factories.keys) if block
|
77
|
-
|
78
|
-
self.class.new(name, abstract_factory: abstract_factory).tap { _1.callbacks = c }
|
79
|
-
end
|
80
|
-
|
81
|
-
def initialize(name, abstract_factory: nil, &def_block)
|
39
|
+
def initialize(name, abstract_factory: nil, callbacks: nil, &def_block)
|
82
40
|
@name = name
|
83
41
|
@def_block = def_block
|
84
42
|
@abstract_factory = abstract_factory.include(Toritori).extend(ClassMethods)
|
@@ -86,6 +44,18 @@ module Nina
|
|
86
44
|
@abstract_factory.build_order_list.freeze
|
87
45
|
@initialization = Initialization.new(@abstract_factory.factories.keys)
|
88
46
|
@assembler = Assembler.new(@abstract_factory)
|
47
|
+
@callbacks = callbacks
|
48
|
+
end
|
49
|
+
|
50
|
+
def copy
|
51
|
+
self.class.new(name, abstract_factory: abstract_factory)
|
52
|
+
end
|
53
|
+
|
54
|
+
def with_callbacks(&block)
|
55
|
+
c = callbacks&.copy || Callbacks.new(abstract_factory.factories.keys)
|
56
|
+
yield c if block
|
57
|
+
|
58
|
+
self.class.new(name, abstract_factory: abstract_factory, callbacks: c)
|
89
59
|
end
|
90
60
|
|
91
61
|
def wrap(delegate: false, &block)
|
@@ -94,7 +64,7 @@ module Nina
|
|
94
64
|
@assembler.inject(
|
95
65
|
@abstract_factory.build_order_list,
|
96
66
|
@initialization.to_h,
|
97
|
-
callbacks: callbacks,
|
67
|
+
callbacks: callbacks.to_h,
|
98
68
|
delegate: delegate
|
99
69
|
)
|
100
70
|
end
|
@@ -105,7 +75,7 @@ module Nina
|
|
105
75
|
@assembler.inject(
|
106
76
|
@abstract_factory.build_order_list.reverse,
|
107
77
|
@initialization.to_h,
|
108
|
-
callbacks: callbacks,
|
78
|
+
callbacks: callbacks.to_h,
|
109
79
|
delegate: delegate
|
110
80
|
)
|
111
81
|
end
|
data/lib/nina/version.rb
CHANGED
data/lib/nina.rb
CHANGED
@@ -31,7 +31,47 @@ module Nina
|
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
+
# Adds ability to delegeate methods via method_missing
|
35
|
+
module MethodMissingDelegation
|
36
|
+
def method_missing(name, *attrs, **kwargs, &block)
|
37
|
+
if (prev = predecessors.detect { |o| o.public_methods.include?(name) })
|
38
|
+
prev.public_send(name, *attrs, **kwargs, &block)
|
39
|
+
else
|
40
|
+
super
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def respond_to_missing?(method_name, _include_private = false)
|
45
|
+
public_methods.detect { |m| m == :predecessor_name } || super
|
46
|
+
end
|
47
|
+
|
48
|
+
def predecessors
|
49
|
+
@predecessors ||= begin
|
50
|
+
obj = self
|
51
|
+
[].tap do |list|
|
52
|
+
list << obj = obj.public_send(obj.predecessor_name) while obj.methods.detect { |m| m == :predecessor_name }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
34
58
|
def self.included(receiver)
|
35
59
|
receiver.extend ClassMethods
|
36
60
|
end
|
61
|
+
|
62
|
+
def self.def_accessor(accessor, on:, to:, delegate: false)
|
63
|
+
on.define_singleton_method(accessor) { to }
|
64
|
+
return unless delegate
|
65
|
+
|
66
|
+
on.define_singleton_method(:predecessor_name) { accessor }
|
67
|
+
on.extend(MethodMissingDelegation)
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.linked_list(build_config, delegate: false)
|
71
|
+
build_order = build_config.keys
|
72
|
+
build_config.each.with_index(-1).inject(nil) do |prev, ((_, object), idx)|
|
73
|
+
Nina.def_accessor(build_order[idx], on: object, to: prev, delegate: delegate) if prev
|
74
|
+
object
|
75
|
+
end
|
76
|
+
end
|
37
77
|
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.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrii Baran
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-01-01 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
|
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
|
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
|
@@ -43,6 +43,8 @@ files:
|
|
43
43
|
- lib/nina.rb
|
44
44
|
- lib/nina/assembler.rb
|
45
45
|
- lib/nina/builder.rb
|
46
|
+
- lib/nina/builder/callbacks.rb
|
47
|
+
- lib/nina/builder/initialization.rb
|
46
48
|
- lib/nina/version.rb
|
47
49
|
homepage: https://github.com/andriy-baran/nina
|
48
50
|
licenses:
|