toritori 0.1.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/Gemfile.lock +1 -1
- data/README.md +8 -12
- data/lib/toritori/factory.rb +22 -19
- data/lib/toritori/version.rb +1 -1
- data/lib/toritori.rb +5 -7
- 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: eaa8ad4915b1a30d7e653060e3b9bf1e245e5933d849bb8e7f62e544295907fc
|
4
|
+
data.tar.gz: 8aa97304d8dcfd2d0c182d31631713cb2b25b530059057c59c24287555fd393e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 443583cf5aeb8cd4a888237a13cec6077b6f1aad57a0187da47420a3ba4c28669e5e7bb6c3773bd8410192be58e26293fd2e3bb22a0564ef56aa76808ca233c3
|
7
|
+
data.tar.gz: 1169e0c5495a9b5f609864d1d64ad76dc380d7f9579707a3e98f0622fe79be7ccde0adacf27417ac560915f3069348f491a9015936aac4bbc7955d8744b4c388
|
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,40 @@
|
|
3
3
|
module Toritori
|
4
4
|
# Generates module that adds support for objects creation
|
5
5
|
class Factory
|
6
|
-
attr_reader :
|
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
|
6
|
+
attr_reader :base_class, :creation_method
|
15
7
|
|
16
8
|
def copy
|
17
|
-
self.class.new(name, base_class: base_class,
|
9
|
+
self.class.new(@name, base_class: @base_class, creation_method: @creation_method)
|
18
10
|
end
|
19
11
|
|
20
|
-
def initialize(name, base_class: nil,
|
12
|
+
def initialize(name, base_class: nil, creation_method: :new)
|
21
13
|
@name = name
|
22
|
-
@
|
14
|
+
@base_class = base_class
|
15
|
+
@creation_method = creation_method
|
23
16
|
end
|
24
17
|
|
25
|
-
def subclass(&block)
|
26
|
-
|
27
|
-
|
28
|
-
@
|
18
|
+
def subclass(produces: nil, creation_method: @creation_method, &block)
|
19
|
+
@base_class = check_base_class(produces) || @base_class
|
20
|
+
@base_class = Class.new(@base_class, &block) if block
|
21
|
+
@creation_method = creation_method
|
29
22
|
end
|
30
23
|
|
31
24
|
def create(*args, **kwargs, &block)
|
32
|
-
|
25
|
+
return @base_class.new(*args, **kwargs, &block) if @creation_method == :new
|
26
|
+
|
27
|
+
@base_class.public_send(@creation_method, *args, **kwargs, &block)
|
33
28
|
end
|
34
29
|
|
35
|
-
|
36
|
-
|
30
|
+
private
|
31
|
+
|
32
|
+
def check_base_class(subclass_const = nil)
|
33
|
+
return unless subclass_const
|
34
|
+
|
35
|
+
::Kernel.raise NotAClassError unless subclass_const.is_a?(::Class)
|
36
|
+
|
37
|
+
::Kernel.raise(SubclassError, "must be a subclass of #{@base_class.inspect}") unless subclass_const <= @base_class
|
38
|
+
|
39
|
+
subclass_const
|
37
40
|
end
|
38
41
|
end
|
39
42
|
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
|
|
@@ -30,10 +28,10 @@ module Toritori
|
|
30
28
|
super
|
31
29
|
subclass.factories = factories.transform_values(&:copy)
|
32
30
|
end
|
33
|
-
end
|
34
31
|
|
35
|
-
|
36
|
-
|
32
|
+
def create(name, *args, **kwargs, &block)
|
33
|
+
factories[name].create(*args, **kwargs, &block)
|
34
|
+
end
|
37
35
|
end
|
38
36
|
|
39
37
|
def self.included(receiver)
|
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.1
|
4
|
+
version: 0.2.1
|
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-12-31 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
|