toritori 0.1.0 → 0.2.0

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: 03d2eef669e357b0d84585f3f04ed0c53ae37674edda3ed875c5983cf0963cb7
4
- data.tar.gz: 0a4a405fab280b0b3cc124503dbfc6c21ca4736f606e2672ae0327b41e9c7dc7
3
+ metadata.gz: 47da200bc6b1c00517984ac052c3f3c1f3eab8dcfb9444158a893fb3e254bef4
4
+ data.tar.gz: 11da3242909586815d5c564c9ab80b04ccdd66b0cc02b96f61d416758c265c3f
5
5
  SHA512:
6
- metadata.gz: a172fc3f47049d3dcd804bc6904d6ec34ea9e4beb5400cae0e3eeb1c25051598ba1c0d380b1172b8af2c311e207f6649fc989596389b0a95c9015100f4ee6c32
7
- data.tar.gz: 7e8b7ac71257f8f108093ba50a5a937c80c22dc17ab0150bc5867e4927a08523e39b073a4f8add5358685684a634b76c24c89220141506d53ed904daa77be878
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
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- toritori (0.1.0)
4
+ toritori (0.2.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
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 do |file_name|
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
- # ... omitied ...
131
- end
122
+ # ... omitted ...
123
+ end
132
124
 
133
125
  class ModernFactory < MyAbstractFactory
134
126
  # Update initialize method
135
- table_factory.subclass.base_class ModernTable
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
@@ -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, &subclass.init)
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, &block)
10
+ def initialize(name, base_class: nil, creation_method: :new)
21
11
  @name = name
22
- @subclass = Subclass.new(base_class, block)
12
+ @base_class = base_class
13
+ @creation_method = creation_method
23
14
  end
24
15
 
25
- def subclass(&block)
26
- return @subclass unless block
27
-
28
- @subclass = Subclass.new(Class.new(base_class, &block), @subclass.init)
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
- cached_instantiator(@subclass).__create__(*args, **kwargs, &block)
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
- def base_class
36
- @subclass.base_class
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Toritori
4
- VERSION = '0.1.0'
4
+ VERSION = '0.2.0'
5
5
  end
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.1.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-06-17 00:00:00.000000000 Z
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