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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 03d2eef669e357b0d84585f3f04ed0c53ae37674edda3ed875c5983cf0963cb7
4
- data.tar.gz: 0a4a405fab280b0b3cc124503dbfc6c21ca4736f606e2672ae0327b41e9c7dc7
3
+ metadata.gz: eaa8ad4915b1a30d7e653060e3b9bf1e245e5933d849bb8e7f62e544295907fc
4
+ data.tar.gz: 8aa97304d8dcfd2d0c182d31631713cb2b25b530059057c59c24287555fd393e
5
5
  SHA512:
6
- metadata.gz: a172fc3f47049d3dcd804bc6904d6ec34ea9e4beb5400cae0e3eeb1c25051598ba1c0d380b1172b8af2c311e207f6649fc989596389b0a95c9015100f4ee6c32
7
- data.tar.gz: 7e8b7ac71257f8f108093ba50a5a937c80c22dc17ab0150bc5867e4927a08523e39b073a4f8add5358685684a634b76c24c89220141506d53ed904daa77be878
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
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- toritori (0.1.0)
4
+ toritori (0.2.1)
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,40 @@
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
6
+ attr_reader :base_class, :creation_method
15
7
 
16
8
  def copy
17
- self.class.new(name, base_class: base_class, &subclass.init)
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, &block)
12
+ def initialize(name, base_class: nil, creation_method: :new)
21
13
  @name = name
22
- @subclass = Subclass.new(base_class, block)
14
+ @base_class = base_class
15
+ @creation_method = creation_method
23
16
  end
24
17
 
25
- def subclass(&block)
26
- return @subclass unless block
27
-
28
- @subclass = Subclass.new(Class.new(base_class, &block), @subclass.init)
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
- cached_instantiator(@subclass).__create__(*args, **kwargs, &block)
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
- def base_class
36
- @subclass.base_class
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
@@ -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.1'
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
 
@@ -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
- def self.default_init
36
- @default_init ||= ->(*args, **kwargs, &block) { new(*args, **kwargs, &block) }
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.0
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-06-17 00:00:00.000000000 Z
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