template_class 1.0.0 → 1.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: 600465ef851b0f80d3a893cef379527402986a6ca048535849d7fd9f769821fb
4
- data.tar.gz: 2d51acb9d3b421458d24bba27e31106f82f9d839d34748597b2860bfb4ab6ad8
3
+ metadata.gz: e4c0985a84c4d73b07449fea319cd108c0a78477fa0975a0a946dcb82d05dbda
4
+ data.tar.gz: 35cc326a7341985c9d3a416fcad8b58a9465f4e72a083d7c4e9d153ed4f312d4
5
5
  SHA512:
6
- metadata.gz: 58d7c41b98d98a4d145c4830e05edfc3234be729baf8a6bcae7b3d2a13797c26b4aa36ec2ac71f0d75531e668e0fafde0e0a9bbced5fda9e0e7933fa5ff69f0e
7
- data.tar.gz: c569ddaf85a09f3bf8c60b667aa06ed313a9e6cf657b05dac11d03782f7a0b56cb231882cb9911532c13438667e2110a76f42e7add1d933bafdd82ce983e2b1f
6
+ metadata.gz: 1cc67fea8a072fd2fcf64a7bb7b17d22ae801b1547dd92cccd27a0e6f4c939870b032112bf845dc0974d8860d797f4e12c104f19437be369de70e8d0009ff21a
7
+ data.tar.gz: f756b227610d4503557b949dde1ed5f908fac9da1f3353a7dd55a7772f84e145eb419a1fad568f0a497d08d772a29a340b20fc839910ceee92baeedda9cc8065
data/CHANGELOG.md CHANGED
@@ -1,12 +1,29 @@
1
1
  # Changelog
2
2
 
3
- [//]: # (
3
+ <!--[//]: # (
4
4
  ## <Release number> <Date YYYY-MM-DD>
5
5
  ### Breaking changes
6
6
  ### Deprecations
7
7
  ### New features
8
8
  ### Bug fixes
9
- )
9
+ )-->
10
+
11
+ ## 1.2.0 2024-08-19
12
+
13
+ ### New features
14
+
15
+ - Bulk instantiation
16
+
17
+ ## 1.1.0 2023-08-31
18
+
19
+ ### New features
20
+
21
+ - Added support for caching modules.
22
+ - Added RBS type signatures.
23
+
24
+ ### Bug fixes
25
+
26
+ - Removed the `Error` class.
10
27
 
11
28
  ## 1.0.0 2023-04-07
12
29
 
data/README.md CHANGED
@@ -58,7 +58,17 @@ end
58
58
 
59
59
  `klass.new` behaves like `Class.new`, with the key difference that it saves the new class in the internal cache *before* it executes the block in the class scope. If you use `Class.new` the specialization still works as expected, but the class is cached *after* the block is executed, so a loop will be created if the code inside the block references the same specialization it is defining.
60
60
 
61
- `klass.new` also redefines `inspect` and `to_s` for the new class, so in strings it will appear with the usual C++ style:
61
+ A module analogue to `klass` is passed as third parameter to the block:
62
+
63
+ ```ruby
64
+ resolve_template_specialization do |item_type, _, mod|
65
+ mod.new do
66
+ ...
67
+ end
68
+ end
69
+ ```
70
+
71
+ `klass.new` and `mod.new` also redefine `inspect` and `to_s` for the new class/module, so in strings it will appear with the usual C++ style:
62
72
 
63
73
  ```ruby
64
74
  List[Integer].to_s # => List<Integer>
@@ -72,6 +82,32 @@ List[:any] = Array
72
82
 
73
83
  Notice that the parameter isn't constrained to classes: you can use any object.
74
84
 
85
+ ### Bulk Instantiation
86
+
87
+ A module (or class) containing multiple templates can include `TemplateClass::BulkInstanceable` to be able to instantiate them in bulk using the same parameter.
88
+
89
+ ```ruby
90
+ module Templates
91
+ include TemplateClass::BulkInstantiable
92
+
93
+ class Template1
94
+ ...
95
+ end
96
+
97
+ class Template2
98
+ ...
99
+ end
100
+ end
101
+
102
+ module Instances
103
+ Templates.bulk_instance Integer, into: self
104
+ end
105
+ ```
106
+
107
+ The new constants `Instances::Template1` and `Instances::Template2` are now defined, and they point respectively to `Templates::Template1[Integer]` and `Templates::Template2[Integer]`.
108
+
109
+ The optional keyword argument `with_overrides`, which defaults to `true` if `Zeitwerk` is defined and to `false` otherwise, allows you to automatically access and reopen the instances in files that follow the Zeitwerk naming conventions (eg. you can reopen `Instances::Template1` in the file `instances/template1.rb`). If `with_overrides` is `false`, you can still reopen the instances, but you need to manually handle the appropriate `requires` in the appropriate order.
110
+
75
111
  ## Plans for future development
76
112
 
77
113
  - Multiple specialization parameters
@@ -0,0 +1,21 @@
1
+ module TemplateClass
2
+ module BulkInstantiable
3
+ extend ActiveSupport::Concern
4
+
5
+ class_methods do
6
+ def bulk_instantiate(*args, into:, with_overrides: defined?(Zeitwerk))
7
+ constants(false)
8
+ .map { |constant_name| const_get(constant_name) }
9
+ .map do |constant|
10
+ into.const_set constant.name.demodulize.to_sym, constant[*args]
11
+ end
12
+ .tap { return unless with_overrides } # rubocop:disable Lint/NonLocalExitFromIterator
13
+ .each do |instance|
14
+ require instance.name.underscore
15
+ rescue LoadError
16
+ nil
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -46,13 +46,43 @@ module TemplateClass
46
46
  klass
47
47
  end
48
48
  end
49
- private_constant :CacheClassConstructor
49
+
50
+ class CacheModuleConstructor
51
+ attr_reader :key
52
+ attr_reader :owner
53
+
54
+ delegate_missing_to :owner
55
+
56
+ def initialize key, owner
57
+ @key = key
58
+ @owner = owner
59
+ end
60
+
61
+ def new &block
62
+ mod = Module.new
63
+ owner[key] = mod
64
+
65
+ outer_self = self
66
+
67
+ mod.define_singleton_method :to_s do
68
+ "#{outer_self.owner}<#{outer_self.key}>"
69
+ end
70
+
71
+ mod.singleton_class.alias_method :inspect, :to_s
72
+
73
+ mod.module_exec(&block)
74
+ mod
75
+ end
76
+ end
77
+
78
+ private_constant :CacheClassConstructor, :CacheModuleConstructor
50
79
 
51
80
  class_methods do
52
81
  def resolve_template_specialization &block
53
82
  cache.default_proc = proc do |h, k|
54
83
  class_constructor = CacheClassConstructor.new k, self
55
- result = block.call k, class_constructor
84
+ module_constructor = CacheModuleConstructor.new k, self
85
+ result = block.call k, class_constructor, module_constructor
56
86
 
57
87
  h[k] = result unless h.key? k
58
88
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TemplateClass
4
- VERSION = '1.0.0'
4
+ VERSION = '1.2.0'
5
5
  end
@@ -1,9 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  require_relative 'template_class/version'
4
-
5
- module TemplateClass
6
- class Error < StandardError; end
7
- end
8
-
9
2
  require_relative 'template_class/template'
3
+ require_relative 'template_class/bulk_instantiable'
@@ -0,0 +1,13 @@
1
+ module TemplateClass
2
+ module Template[T]
3
+ interface _CacheClassConstructor
4
+ def new: (?Class base_class) { () [self: Class] -> void } -> Class
5
+ end
6
+
7
+ interface _CacheModuleConstructor
8
+ def new: () { () [self: Module] -> void } -> Module
9
+ end
10
+
11
+ def resolve_template_specialization: () { (T key, _CacheClassConstructor klass, _CacheModuleConstructor mod) -> Class } -> void
12
+ end
13
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: template_class
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Moku S.r.l.
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2023-04-07 00:00:00.000000000 Z
12
+ date: 2024-08-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -43,14 +43,14 @@ files:
43
43
  - ".rubocop.yml"
44
44
  - CHANGELOG.md
45
45
  - Gemfile
46
- - Gemfile.lock
47
46
  - LICENSE
48
47
  - README.md
49
48
  - Rakefile
50
49
  - lib/template_class.rb
50
+ - lib/template_class/bulk_instantiable.rb
51
51
  - lib/template_class/template.rb
52
52
  - lib/template_class/version.rb
53
- - sig/template_class.rbs
53
+ - sig/lib/template_class/template.rbs
54
54
  homepage: https://github.com/moku-io/template_class
55
55
  licenses:
56
56
  - MIT
@@ -73,7 +73,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
73
73
  - !ruby/object:Gem::Version
74
74
  version: '0'
75
75
  requirements: []
76
- rubygems_version: 3.4.6
76
+ rubygems_version: 3.5.11
77
77
  signing_key:
78
78
  specification_version: 4
79
79
  summary: A way to define templated classes, in a similar fashion to C++ templates.
data/Gemfile.lock DELETED
@@ -1,57 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- template_class (1.0.0)
5
-
6
- GEM
7
- remote: https://rubygems.org/
8
- specs:
9
- ast (2.4.2)
10
- diff-lcs (1.5.0)
11
- json (2.6.3)
12
- parallel (1.22.1)
13
- parser (3.2.1.1)
14
- ast (~> 2.4.1)
15
- rainbow (3.1.1)
16
- rake (13.0.6)
17
- regexp_parser (2.7.0)
18
- rexml (3.2.5)
19
- rspec (3.12.0)
20
- rspec-core (~> 3.12.0)
21
- rspec-expectations (~> 3.12.0)
22
- rspec-mocks (~> 3.12.0)
23
- rspec-core (3.12.1)
24
- rspec-support (~> 3.12.0)
25
- rspec-expectations (3.12.2)
26
- diff-lcs (>= 1.2.0, < 2.0)
27
- rspec-support (~> 3.12.0)
28
- rspec-mocks (3.12.4)
29
- diff-lcs (>= 1.2.0, < 2.0)
30
- rspec-support (~> 3.12.0)
31
- rspec-support (3.12.0)
32
- rubocop (1.48.1)
33
- json (~> 2.3)
34
- parallel (~> 1.10)
35
- parser (>= 3.2.0.0)
36
- rainbow (>= 2.2.2, < 4.0)
37
- regexp_parser (>= 1.8, < 3.0)
38
- rexml (>= 3.2.5, < 4.0)
39
- rubocop-ast (>= 1.26.0, < 2.0)
40
- ruby-progressbar (~> 1.7)
41
- unicode-display_width (>= 2.4.0, < 3.0)
42
- rubocop-ast (1.27.0)
43
- parser (>= 3.2.1.0)
44
- ruby-progressbar (1.13.0)
45
- unicode-display_width (2.4.2)
46
-
47
- PLATFORMS
48
- arm64-darwin-22
49
-
50
- DEPENDENCIES
51
- rake (~> 13.0)
52
- rspec (~> 3.0)
53
- rubocop (~> 1.21)
54
- template_class!
55
-
56
- BUNDLED WITH
57
- 2.4.6
@@ -1,4 +0,0 @@
1
- module TemplateClass
2
- VERSION: String
3
- # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
- end