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 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