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