inoculate 0.3.0 → 0.4.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 +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +53 -1
- data/lib/inoculate/configurer.rb +9 -0
- data/lib/inoculate/manufacturer.rb +50 -17
- data/lib/inoculate/version.rb +1 -1
- data/sig/inoculate.rbs +2 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7bd8610b9bbde1304734505a64fdf22c8665961e3b02d93171ac4fc6ccf313aa
|
4
|
+
data.tar.gz: 66ee174fa4bd02dfd671a39a946a8343da1d63bb88f9be05ee94816d033a5e4e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bbc2655324e68cd2ad977192b81f9cbef0d63b72da91f05521c59eb91f1d58993da68dbcd8d4f6b69be5e5d93708e847f567955f80cb042761e187b64c1bcdbc
|
7
|
+
data.tar.gz: ef316f9b6e6dfa9cd42811f8af5082f402d0c03478a280a2728b61ce9c706a9e0b1cd0249921d18818cfa85b28ccf81969a1330744c3d8d19e95e5fd4f73a81c
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -25,6 +25,7 @@ It provides several life-cycles and provides dependency access through private a
|
|
25
25
|
1. [Dependency Life Cycles](#dependency-life-cycles)
|
26
26
|
1. [Transient](#transient)
|
27
27
|
2. [Instance](#instance)
|
28
|
+
3. [Singleton](#singleton)
|
28
29
|
2. [Renaming the Declaration API](#renaming-the-declaration-api)
|
29
30
|
3. [Hide Your Dependency on Inoculate](#hide-your-dependency-on-inoculate)
|
30
31
|
3. [Installation](#installation)
|
@@ -100,13 +101,16 @@ class Example
|
|
100
101
|
end
|
101
102
|
end
|
102
103
|
|
103
|
-
|
104
|
+
a = Example.new
|
105
|
+
puts a, a, a
|
104
106
|
```
|
105
107
|
|
106
108
|
This results in:
|
107
109
|
|
108
110
|
```
|
109
111
|
Count is: 0
|
112
|
+
Count is: 0
|
113
|
+
Count is: 0
|
110
114
|
=> nil
|
111
115
|
```
|
112
116
|
|
@@ -158,6 +162,54 @@ This results in:
|
|
158
162
|
=> nil
|
159
163
|
```
|
160
164
|
|
165
|
+
#### Singleton
|
166
|
+
Singleton dependencies are constructed once.
|
167
|
+
|
168
|
+
```ruby
|
169
|
+
class Counter
|
170
|
+
attr_reader :count
|
171
|
+
|
172
|
+
def initialize
|
173
|
+
@count = 0
|
174
|
+
end
|
175
|
+
|
176
|
+
def inc
|
177
|
+
@count += 1
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
Inoculate.initialize do |config|
|
182
|
+
config.singleton(:counter) { Counter.new }
|
183
|
+
end
|
184
|
+
|
185
|
+
class Example
|
186
|
+
include Inoculate::Porter
|
187
|
+
inoculate_with :counter
|
188
|
+
|
189
|
+
def initialize(name)
|
190
|
+
@name = name
|
191
|
+
end
|
192
|
+
|
193
|
+
def to_s
|
194
|
+
counter.inc
|
195
|
+
"[#{@name}] Count is: #{counter.count}"
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
a = Example.new("a")
|
200
|
+
b = Example.new("b")
|
201
|
+
puts a, a, b
|
202
|
+
```
|
203
|
+
|
204
|
+
This results in:
|
205
|
+
|
206
|
+
```
|
207
|
+
[a] Count is: 1
|
208
|
+
[a] Count is: 2
|
209
|
+
[b] Count is: 3
|
210
|
+
=> nil
|
211
|
+
```
|
212
|
+
|
161
213
|
### Renaming the Declaration API
|
162
214
|
The `inoculate_with` API is named to avoid immediate collisions with other modules
|
163
215
|
and code you may have. You can use it as-is, or rename it to something you see fit
|
data/lib/inoculate/configurer.rb
CHANGED
@@ -27,6 +27,15 @@ module Inoculate
|
|
27
27
|
nil
|
28
28
|
end
|
29
29
|
|
30
|
+
# Register a singleton dependency.
|
31
|
+
# @see Manufacturer#singleton
|
32
|
+
#
|
33
|
+
# @since 0.4.0
|
34
|
+
def singleton(name, &block)
|
35
|
+
manufacturer.singleton(name, &block)
|
36
|
+
nil
|
37
|
+
end
|
38
|
+
|
30
39
|
private
|
31
40
|
|
32
41
|
attr_reader :manufacturer
|
@@ -5,7 +5,6 @@ require "digest"
|
|
5
5
|
module Inoculate
|
6
6
|
# Registers and builds dependency injection modules.
|
7
7
|
# @todo singleton life cycle
|
8
|
-
# @todo instance life cycle
|
9
8
|
# @todo thread singleton life cycle
|
10
9
|
#
|
11
10
|
# @since 0.1.0
|
@@ -40,16 +39,7 @@ module Inoculate
|
|
40
39
|
#
|
41
40
|
# @since 0.1.0
|
42
41
|
def transient(name, &block)
|
43
|
-
|
44
|
-
raise Errors::AlreadyRegistered if @registered_blueprints.has_key? name
|
45
|
-
raise Errors::RequiresCallable if block.nil?
|
46
|
-
|
47
|
-
blueprint_name = name.to_sym
|
48
|
-
@registered_blueprints[blueprint_name] = {
|
49
|
-
lifecycle: :transient,
|
50
|
-
factory: block,
|
51
|
-
accessor_module: build_module(blueprint_name, :transient, block)
|
52
|
-
}
|
42
|
+
register_blueprint(name, :transient, &block)
|
53
43
|
end
|
54
44
|
|
55
45
|
# Register an instance dependency.
|
@@ -72,26 +62,54 @@ module Inoculate
|
|
72
62
|
#
|
73
63
|
# @since 0.3.0
|
74
64
|
def instance(name, &block)
|
65
|
+
register_blueprint(name, :instance, &block)
|
66
|
+
end
|
67
|
+
|
68
|
+
# Register a singleton dependency.
|
69
|
+
#
|
70
|
+
# A singleton dependency gets created once.
|
71
|
+
#
|
72
|
+
# @example With a block
|
73
|
+
# manufacturer.singleton(:sha1_hasher) { Digest::SHA1.new }
|
74
|
+
#
|
75
|
+
# @example With a Proc
|
76
|
+
# manufacturer.singleton(:sha1_hasher, &-> { Digest::SHA1.new })
|
77
|
+
#
|
78
|
+
# @param name [Symbol, #to_sym] the dependency name which will be used to access it
|
79
|
+
# @param block [Block, Proc] a factory method to build the dependency
|
80
|
+
#
|
81
|
+
# @raise [Errors::RequiresCallable] if no block is provided
|
82
|
+
# @raise [Errors::InvalidName] if the name is not a symbol, cannot be converted to a symbol,
|
83
|
+
# or is not a valid attribute name
|
84
|
+
# @raise [Errors::AlreadyRegistered] if the name has been registered previously
|
85
|
+
#
|
86
|
+
# @since 0.4.0
|
87
|
+
def singleton(name, &block)
|
88
|
+
register_blueprint(name, :singleton, &block)
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
def register_blueprint(name, lifecycle, &block)
|
75
94
|
validate_dependency_name name
|
76
95
|
raise Errors::AlreadyRegistered if @registered_blueprints.has_key? name
|
77
96
|
raise Errors::RequiresCallable if block.nil?
|
78
97
|
|
79
98
|
blueprint_name = name.to_sym
|
80
99
|
@registered_blueprints[blueprint_name] = {
|
81
|
-
lifecycle:
|
100
|
+
lifecycle: lifecycle,
|
82
101
|
factory: block,
|
83
|
-
accessor_module: build_module(blueprint_name,
|
102
|
+
accessor_module: build_module(blueprint_name, lifecycle, block)
|
84
103
|
}
|
85
104
|
end
|
86
105
|
|
87
|
-
private
|
88
|
-
|
89
106
|
def build_module(name, lifecycle, factory)
|
90
|
-
module_name = "I#{
|
107
|
+
module_name = "I#{hash_name(name)}"
|
91
108
|
module_body =
|
92
109
|
case lifecycle
|
93
110
|
when :transient then build_transient(name, factory)
|
94
111
|
when :instance then build_instance(name, factory)
|
112
|
+
when :singleton then build_singleton(name, factory)
|
95
113
|
else raise ArgumentError, "Life cycle #{lifecycle} is not valid. Something has gone very wrong."
|
96
114
|
end
|
97
115
|
|
@@ -105,7 +123,7 @@ module Inoculate
|
|
105
123
|
end
|
106
124
|
|
107
125
|
def build_instance(name, factory)
|
108
|
-
cache_variable_name = "@icache_#{
|
126
|
+
cache_variable_name = "@icache_#{hash_name(name)}"
|
109
127
|
Module.new do
|
110
128
|
define_method(name) do
|
111
129
|
instance_variable_set(cache_variable_name, factory.call) unless instance_variable_defined?(cache_variable_name)
|
@@ -115,6 +133,17 @@ module Inoculate
|
|
115
133
|
end
|
116
134
|
end
|
117
135
|
|
136
|
+
def build_singleton(name, factory)
|
137
|
+
cache_variable_name = "@@icache_#{hash_name(name)}"
|
138
|
+
Module.new do |mod|
|
139
|
+
define_method(name) do
|
140
|
+
mod.class_variable_set(cache_variable_name, factory.call) unless mod.class_variable_defined?(cache_variable_name)
|
141
|
+
mod.class_variable_get(cache_variable_name)
|
142
|
+
end
|
143
|
+
private name
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
118
147
|
def validate_dependency_name(name)
|
119
148
|
raise Errors::InvalidName, "name must be a symbol or convert to one" unless name.respond_to? :to_sym
|
120
149
|
begin
|
@@ -123,5 +152,9 @@ module Inoculate
|
|
123
152
|
raise Errors::InvalidName, "name must be a valid attr_reader"
|
124
153
|
end
|
125
154
|
end
|
155
|
+
|
156
|
+
def hash_name(name)
|
157
|
+
Digest::SHA1.hexdigest(name.to_s)
|
158
|
+
end
|
126
159
|
end
|
127
160
|
end
|
data/lib/inoculate/version.rb
CHANGED
data/sig/inoculate.rbs
CHANGED
@@ -34,6 +34,7 @@ module Inoculate
|
|
34
34
|
attr_reader registered_blueprints: Hash[builder_name, blueprint]
|
35
35
|
def transient: (builder_name | _ToSymbol) { () -> void } -> void
|
36
36
|
def instance: (builder_name | _ToSymbol) { () -> void } -> void
|
37
|
+
def singleton: (builder_name | _ToSymbol) { () -> void } -> void
|
37
38
|
end
|
38
39
|
|
39
40
|
class Configurer
|
@@ -41,6 +42,7 @@ module Inoculate
|
|
41
42
|
|
42
43
|
def transient: (builder_name | _ToSymbol) { () -> void } -> nil
|
43
44
|
def instance: (builder_name | _ToSymbol) { () -> void } -> nil
|
45
|
+
def singleton: (builder_name | _ToSymbol) { () -> void } -> nil
|
44
46
|
|
45
47
|
private
|
46
48
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: inoculate
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stephan Tarulli
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-10-
|
11
|
+
date: 2022-10-13 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: |
|
14
14
|
Inoculate is a small, thread-safe dependency injection library configured entirely with Ruby.
|