toritori 0.1.0 → 0.2.0
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 +12 -0
- data/Gemfile.lock +1 -1
- data/README.md +8 -12
- data/lib/toritori/factory.rb +21 -20
- data/lib/toritori/version.rb +1 -1
- data/lib/toritori.rb +2 -8
- metadata +2 -4
- data/lib/toritori/factory/instantiator.rb +0 -24
- data/lib/toritori/factory/subclass.rb +0 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 47da200bc6b1c00517984ac052c3f3c1f3eab8dcfb9444158a893fb3e254bef4
|
4
|
+
data.tar.gz: 11da3242909586815d5c564c9ab80b04ccdd66b0cc02b96f61d416758c265c3f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4887c90e93f2a13c8942b6b7028f957dead740214ebdadc4717f71ef5005a7dd672c3559b9523bc52e4e741c94cfba637ec4b27215eb31c1bf003a6a027130fd
|
7
|
+
data.tar.gz: cf38a85c4d6efd4989f49740dfeb373780325b88007d34bbb18841b7efb6987c924d80516229cf6c17a389471ca772b1eafe26fad792c752b31eda65e68a41bc
|
data/CHANGELOG.md
CHANGED
@@ -0,0 +1,12 @@
|
|
1
|
+
## [0.2.0] - 2023-07-05
|
2
|
+
|
3
|
+
### Improved
|
4
|
+
* Performace and memory usage
|
5
|
+
|
6
|
+
### Changed
|
7
|
+
* The way to specify different method to create object (default `new`)
|
8
|
+
* `factory.subclass` is a method now, not a "value object"
|
9
|
+
|
10
|
+
## [0.1.0] - 2023-05-18
|
11
|
+
|
12
|
+
- Initial release
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -66,10 +66,7 @@ The library defaults is to use `new` method for instantiation and bypass paramet
|
|
66
66
|
class MyAbstractFactory
|
67
67
|
include Toritori
|
68
68
|
|
69
|
-
factory :file, produces: File
|
70
|
-
# Every method is called on File
|
71
|
-
open(file_name, 'r')
|
72
|
-
end
|
69
|
+
factory :file, produces: File, creation_method: :open
|
73
70
|
end
|
74
71
|
|
75
72
|
MyAbstractFactory.file_factory.create('/dev/null') # => #<File @path='/dev/null'>
|
@@ -112,11 +109,6 @@ class ModernFactory < MyAbstractFactory
|
|
112
109
|
|
113
110
|
attr_reader :wifi
|
114
111
|
end
|
115
|
-
|
116
|
-
# Notify factory about new way to create objects
|
117
|
-
chair_factory.subclass.init do |width, wifi:|
|
118
|
-
new(width, wifi)
|
119
|
-
end
|
120
112
|
end
|
121
113
|
|
122
114
|
modern_chair = ModernFactory.chair_factory.create(2500, wifi: false)
|
@@ -127,12 +119,16 @@ The subclass (`ModernFactory`) will gen a copy of `factories` so you can customi
|
|
127
119
|
Sometimes when subclass definition is big it is better to put it into a separate file. To make the library to use that sub-class:
|
128
120
|
```ruby
|
129
121
|
class ModernTable < MyAbstractFactory.table_factory.base_class
|
130
|
-
# ...
|
131
|
-
end
|
122
|
+
# ... omitted ...
|
123
|
+
end
|
132
124
|
|
133
125
|
class ModernFactory < MyAbstractFactory
|
134
126
|
# Update initialize method
|
135
|
-
table_factory.subclass
|
127
|
+
table_factory.subclass(produces: ModernTable, creation_method: :produce) do
|
128
|
+
def self.produce(...)
|
129
|
+
new(...)
|
130
|
+
end
|
131
|
+
end
|
136
132
|
|
137
133
|
table_factory.create # => #<ModernTable>
|
138
134
|
end
|
data/lib/toritori/factory.rb
CHANGED
@@ -3,37 +3,38 @@
|
|
3
3
|
module Toritori
|
4
4
|
# Generates module that adds support for objects creation
|
5
5
|
class Factory
|
6
|
-
attr_reader :name
|
7
|
-
|
8
|
-
def cached_instantiator(subclass)
|
9
|
-
id = [subclass.base_class.object_id, subclass.init.object_id].join('_')
|
10
|
-
@cache ||= ::Hash.new do |h, key|
|
11
|
-
h[key] = Instantiator.new(subclass)
|
12
|
-
end
|
13
|
-
@cache[id]
|
14
|
-
end
|
15
|
-
|
16
6
|
def copy
|
17
|
-
self.class.new(name, base_class: base_class,
|
7
|
+
self.class.new(@name, base_class: @base_class, creation_method: @creation_method)
|
18
8
|
end
|
19
9
|
|
20
|
-
def initialize(name, base_class: nil,
|
10
|
+
def initialize(name, base_class: nil, creation_method: :new)
|
21
11
|
@name = name
|
22
|
-
@
|
12
|
+
@base_class = base_class
|
13
|
+
@creation_method = creation_method
|
23
14
|
end
|
24
15
|
|
25
|
-
def subclass(&block)
|
26
|
-
|
27
|
-
|
28
|
-
@
|
16
|
+
def subclass(produces: nil, creation_method: @creation_method, &block)
|
17
|
+
@base_class = check_base_class(produces) || @base_class
|
18
|
+
@base_class = Class.new(@base_class, &block) if block
|
19
|
+
@creation_method = creation_method
|
29
20
|
end
|
30
21
|
|
31
22
|
def create(*args, **kwargs, &block)
|
32
|
-
|
23
|
+
return @base_class.new(*args, **kwargs, &block) if @creation_method == :new
|
24
|
+
|
25
|
+
@base_class.public_send(@creation_method, *args, **kwargs, &block)
|
33
26
|
end
|
34
27
|
|
35
|
-
|
36
|
-
|
28
|
+
private
|
29
|
+
|
30
|
+
def check_base_class(subclass_const = nil)
|
31
|
+
return unless subclass_const
|
32
|
+
|
33
|
+
::Kernel.raise NotAClassError unless subclass_const.is_a?(::Class)
|
34
|
+
|
35
|
+
::Kernel.raise(SubclassError, "must be a subclass of #{@base_class.inspect}") unless subclass_const <= @base_class
|
36
|
+
|
37
|
+
subclass_const
|
37
38
|
end
|
38
39
|
end
|
39
40
|
end
|
data/lib/toritori/version.rb
CHANGED
data/lib/toritori.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'toritori/factory/instantiator'
|
4
|
-
require 'toritori/factory/subclass'
|
5
3
|
require 'toritori/factory'
|
6
4
|
require 'toritori/version'
|
7
5
|
|
@@ -21,8 +19,8 @@ module Toritori
|
|
21
19
|
@factories = other
|
22
20
|
end
|
23
21
|
|
24
|
-
def factory(name, produces: Class.new, &block)
|
25
|
-
factories[name] = Toritori::Factory.new(name, base_class: produces, &block)
|
22
|
+
def factory(name, produces: Class.new, creation_method: :new, &block)
|
23
|
+
factories[name] = Toritori::Factory.new(name, base_class: produces, creation_method: creation_method, &block)
|
26
24
|
define_singleton_method(:"#{name}_factory") { factories[name] }
|
27
25
|
end
|
28
26
|
|
@@ -32,10 +30,6 @@ module Toritori
|
|
32
30
|
end
|
33
31
|
end
|
34
32
|
|
35
|
-
def self.default_init
|
36
|
-
@default_init ||= ->(*args, **kwargs, &block) { new(*args, **kwargs, &block) }
|
37
|
-
end
|
38
|
-
|
39
33
|
def self.included(receiver)
|
40
34
|
receiver.extend ClassMethods
|
41
35
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: toritori
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
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-
|
11
|
+
date: 2023-08-21 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Create factories with DSL
|
14
14
|
email:
|
@@ -32,8 +32,6 @@ files:
|
|
32
32
|
- bin/setup
|
33
33
|
- lib/toritori.rb
|
34
34
|
- lib/toritori/factory.rb
|
35
|
-
- lib/toritori/factory/instantiator.rb
|
36
|
-
- lib/toritori/factory/subclass.rb
|
37
35
|
- lib/toritori/version.rb
|
38
36
|
- toritori.gemspec
|
39
37
|
homepage: https://github.com/andriy-baran/toritori
|
@@ -1,24 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Toritori
|
4
|
-
class Factory
|
5
|
-
# Utility class that evaluates initalization procs
|
6
|
-
class Instantiator < BasicObject
|
7
|
-
def initialize(subclass)
|
8
|
-
@subclass = subclass
|
9
|
-
@type = subclass.base_class
|
10
|
-
define_singleton_method(:__create__, &subclass.init)
|
11
|
-
end
|
12
|
-
|
13
|
-
def method_missing(method, *args, **kwargs, &block)
|
14
|
-
return super unless @type.respond_to?(method)
|
15
|
-
|
16
|
-
@type.public_send(method, *args, **kwargs, &block)
|
17
|
-
end
|
18
|
-
|
19
|
-
def respond_to_missing?(method, include_private = false)
|
20
|
-
@type.respond_to?(method, include_private) || super
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Toritori
|
4
|
-
class Factory
|
5
|
-
# Utility class that stores initalization procs
|
6
|
-
class Subclass < BasicObject
|
7
|
-
def initialize(base_class, init)
|
8
|
-
@init = init || ::Toritori.default_init
|
9
|
-
@base_class = base_class
|
10
|
-
end
|
11
|
-
|
12
|
-
def init(&block)
|
13
|
-
return @init unless block
|
14
|
-
|
15
|
-
@init = block
|
16
|
-
end
|
17
|
-
|
18
|
-
def base_class(subclass_const = nil)
|
19
|
-
return @base_class unless subclass_const
|
20
|
-
|
21
|
-
::Kernel.raise NotAClassError unless subclass_const.is_a?(::Class)
|
22
|
-
unless subclass_const <= @base_class
|
23
|
-
::Kernel.raise(SubclassError, "must be a subclass of #{@base_class.inspect}")
|
24
|
-
end
|
25
|
-
|
26
|
-
@base_class = subclass_const
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|