nxt_registry 0.2.1 → 0.3.4

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: 6851c2c3d6dde7438aa6abe438153d4126ea962f948d472a37d8b958830390f3
4
- data.tar.gz: '02158d50dd9af0686bd4427e1c41853dca588e686b9a02381263c94700093398'
3
+ metadata.gz: b3c4dec7379f1076565a8fa2306e9aba2bfbd12f1191648929635db61a7b4a94
4
+ data.tar.gz: '081a471bb51c5e53089ee8341f439b8b70bdb22bb45c24add42673210ecacd0c'
5
5
  SHA512:
6
- metadata.gz: 04c65be146020a7e3c1e1fa6587cdb9efb0c4b2ab6d76741855fe99a0246e4a5ace755c3184678164f388d41a45ddc6a03c39298c0038ecf13e454f77a5deb74
7
- data.tar.gz: f992919cf0d07da41e411b7dff32410678b664f4a12a47e350e0d51e239c6864eaeb549aca4518eae1f122640b99274897e6bc4b39bb6889634e6a32ee137931
6
+ metadata.gz: 7913f84e7bfea3f58efd487eb9bbdc34c988fb3297101aa52525e530c8a6bec5b2d5bc6dfc81bd188f4145c99a74dbbb65b556b6acf847b16df529a65b612999
7
+ data.tar.gz: 59fe97c3fe3bbc653bd63f6e7bd835d08189136fc328d9ce0fa62e8199dcc311fa152d2d0ebedb1b7a580b3ef20a6253dfbb02c605a700f88a42076bd57935be
@@ -1,3 +1,34 @@
1
+ # v0.3.4 2020-12-04
2
+
3
+ - Bring back Singleton
4
+ - Fix mistakes in readme
5
+
6
+ # v0.3.3 2020-11-24
7
+
8
+ - Fix: Pass key to resolver instead of value
9
+
10
+ # v0.3.2 2020-09-29
11
+
12
+ - Fix interface definition
13
+
14
+ # v0.3.1 2020-09-23
15
+
16
+ - Allow to define custom accessors for registries
17
+
18
+ # v0.3.0 2020-09-10
19
+
20
+ ### Breaking Changes
21
+
22
+ - Toggled interface for resolve(!) and register(!)
23
+ - Allow to register values in nested registries
24
+ - Rename nested method into level
25
+ - Provide registry readers
26
+ - Remove Singleton extension
27
+ - Allow to resolve paths
28
+ - Pass key to default block when it takes an argument
29
+
30
+ [Compare v0.2.1...v0.3.0](https://github.com/nxt-insurance/nxt_registry/compare/v0.2.1...v0.3.0)
31
+
1
32
  # v0.2.1 2020-08-14
2
33
 
3
34
  ### Fixed
@@ -1,13 +1,13 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- nxt_registry (0.2.1)
4
+ nxt_registry (0.3.4)
5
5
  activesupport
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
- activesupport (6.0.3.2)
10
+ activesupport (6.0.3.4)
11
11
  concurrent-ruby (~> 1.0, >= 1.0.2)
12
12
  i18n (>= 0.7, < 2)
13
13
  minitest (~> 5.1)
@@ -19,30 +19,30 @@ GEM
19
19
  i18n (1.8.5)
20
20
  concurrent-ruby (~> 1.0)
21
21
  method_source (1.0.0)
22
- minitest (5.14.1)
22
+ minitest (5.14.2)
23
23
  pry (0.13.1)
24
24
  coderay (~> 1.1)
25
25
  method_source (~> 1.0)
26
26
  rake (12.3.3)
27
- rspec (3.9.0)
28
- rspec-core (~> 3.9.0)
29
- rspec-expectations (~> 3.9.0)
30
- rspec-mocks (~> 3.9.0)
31
- rspec-core (3.9.2)
32
- rspec-support (~> 3.9.3)
33
- rspec-expectations (3.9.2)
27
+ rspec (3.10.0)
28
+ rspec-core (~> 3.10.0)
29
+ rspec-expectations (~> 3.10.0)
30
+ rspec-mocks (~> 3.10.0)
31
+ rspec-core (3.10.0)
32
+ rspec-support (~> 3.10.0)
33
+ rspec-expectations (3.10.0)
34
34
  diff-lcs (>= 1.2.0, < 2.0)
35
- rspec-support (~> 3.9.0)
36
- rspec-mocks (3.9.1)
35
+ rspec-support (~> 3.10.0)
36
+ rspec-mocks (3.10.0)
37
37
  diff-lcs (>= 1.2.0, < 2.0)
38
- rspec-support (~> 3.9.0)
39
- rspec-support (3.9.3)
38
+ rspec-support (~> 3.10.0)
39
+ rspec-support (3.10.0)
40
40
  rspec_junit_formatter (0.4.1)
41
41
  rspec-core (>= 2, < 4, != 2.12.0)
42
42
  thread_safe (0.3.6)
43
- tzinfo (1.2.7)
43
+ tzinfo (1.2.8)
44
44
  thread_safe (~> 0.1)
45
- zeitwerk (2.4.0)
45
+ zeitwerk (2.4.2)
46
46
 
47
47
  PLATFORMS
48
48
  ruby
data/README.md CHANGED
@@ -2,8 +2,8 @@
2
2
 
3
3
  # NxtRegistry
4
4
 
5
- NxtRegistry is a simple implementation of the container pattern. It allows you to register and resolve values in nested
6
- structures by allowing nesting registries into each other. In theory this can be indefinitely deep.
5
+ `NxtRegistry` is a simple implementation of the container pattern. It allows you to register and resolve values in nested
6
+ structures.
7
7
 
8
8
  ## Installation
9
9
 
@@ -23,61 +23,27 @@ Or install it yourself as:
23
23
 
24
24
  ## Usage
25
25
 
26
- ### Instance Level
26
+ ### Simple use case
27
+
28
+ ## Instance Level
29
+
30
+ If you simply need a single global instance of a registry include `NxtRegistry::Singleton`:
27
31
 
28
32
  ```ruby
29
33
  class Example
30
- include NxtRegistry
34
+ include NxtRegistry::Singleton
31
35
 
32
- def passengers
33
- @passengers ||= begin
34
- registry :from do
35
- nested :to do
36
- nested :via, memoize: true, call: true, default: -> { [] } do
37
- attrs %i[train car plane horse] # restrict the attributes that can be registered
38
- resolver ->(value) { value } # do something with your registered value here
39
- transform_keys ->(key) { key.upcase } # transform keys
40
- end
41
- end
42
- end
43
- end
36
+ registry do
37
+ register(:ruby, 'Stone')
38
+ register(:python, 'Snake')
39
+ register(:javascript, 'undefined')
44
40
  end
45
41
  end
46
42
 
47
- example = Example.new
48
- # Based on the naming of the registry and its nesting you are provided with a simple interface
49
- # that allows you to resolve and register values by name
50
-
51
- # Register an array with a value by calling the accessor with a key, value pair
52
- example.passengers.from(:a).to(:b).via(:train, ['Andy']) # => ['Andy']
53
-
54
- # In case you try to register the same key again you will get an error
55
- example.passengers.from(:a).to(:b).via(:train, ['Andy'])
56
- # => NxtRegistry::Errors::KeyAlreadyRegisteredError
57
- # (Key 'train' already registered in registry 'from.to.via')
58
- # NxtRegistry::Errors::KeyAlreadyRegisteredError inherits from KeyError
59
-
60
- # You can force values on the registry by using the bang method
61
- example.passengers.from(:a).to(:b).via!(:train, ['Andreas'])
62
-
63
- # Similarly you can try to resolve values softly
64
- # (meaning no KeyNotRegisteredError will be raised when nothing was registered)
65
- example.passengers.from(:a).to(:b).via!(:train)
66
- # Since there is a default defined for this registry, it does not make any sense
67
- # since there is always a value. But you get the point...
68
-
69
- # Resolve values by calling the accessor with the key only
70
- # In this case the default is returned because nothing was registered yet
71
- example.passengers.from(:a).to(:b).via(:hyperloop) # []
72
-
73
- # Appending values to a default array
74
- example.passengers.from(:a).to(:b).via(:car) << 'Lütfi' # => ['Lütif']
75
- example.passengers.from(:a).to(:b).via(:plane) += %w[Nils Rapha]
76
- example.passengers.from(:a).to(:b).via(:plane) # => ['Nils', 'Rapha']
77
-
43
+ Example.resolve(:ruby) # => 'Stone'
78
44
  ```
79
45
 
80
- Alternatively you can create an instance of NxtRegistry::Registry.new('name', **options, &config)
46
+ Alternatively you can simply create instances of `NxtRegistry::Registry`:
81
47
 
82
48
  ```ruby
83
49
  registry = NxtRegistry::Registry.new do
@@ -90,52 +56,114 @@ registry.resolve(:aki) # => 'Aki'
90
56
 
91
57
  ```
92
58
 
93
- ### Class Level
59
+ ## Class Level
60
+
61
+ You can also add registries on the class level simply by extending your class with `NxtRegistry`
94
62
 
95
63
  ```ruby
96
- class SimpleExample
97
- # By extending NxtRegistry::Singleton you get a super simple class level interface to an underlying instance of a :registry
98
- extend NxtRegistry::Singleton
99
-
100
- registry do
101
- # procs are called directly if not defined otherwise
64
+ class OtherExample
65
+ extend NxtRegistry
66
+
67
+ registry(:errors) do
102
68
  register(KeyError, ->(error) { puts 'KeyError handler' } )
103
69
  register(ArgumentError, ->(error) { puts 'ArgumentError handler' } )
104
- # Custom key error handlers
105
- on_key_already_registered ->(key) { raise "Key was already registered dude: #{key}" }
106
- on_key_not_registered ->(key) { raise "Key was never registered dude: #{key}" }
107
70
  end
71
+
72
+ registry(:country_codes) do
73
+ register(:germany, :de)
74
+ register(:england, :uk)
75
+ register(:france, :fr)
76
+ end
108
77
  end
109
-
110
- SimpleExample.resolve(KeyError)
111
- # Alternatively: SimpleExample.registry.resolve(KeyError)
112
- # Or: SimpleExample.instance.resolve(KeyError)
78
+
79
+ OtherExample.registry(:errors).resolve(KeyError)
113
80
  # KeyError handler
114
81
  # => nil
115
-
82
+ OtherExample.registry(:country_codes).resolve(:germany)
83
+ # => :de
116
84
  ```
85
+ ### Readers
86
+
87
+ Access your defined registries with the `registry(:country_code)` method.
88
+
89
+ ### Nesting registries
90
+
91
+ You can also simply nest registries like so:
117
92
 
118
93
  ```ruby
119
- class OtherExample
94
+ class Nested
120
95
  extend NxtRegistry
121
96
 
122
- # By passing a block to :registry you can directly register your values inline
123
- REGISTRY = registry(:errors) do
124
- # procs are called directly if not defined otherwise
125
- register(KeyError, ->(error) { puts 'KeyError handler' } )
126
- register(ArgumentError, ->(error) { puts 'ArgumentError handler' } )
97
+ registry :developers do
98
+ register(:frontend) do
99
+ register(:igor, 'Igor')
100
+ register(:ben, 'Ben')
101
+ end
102
+
103
+ register(:backend) do
104
+ register(:rapha, 'Rapha')
105
+ register(:aki, 'Aki')
106
+ end
127
107
  end
128
108
  end
129
109
 
130
- # Instead of using the name of the registry, you can also always call register and resolve on the
131
- # level where you want to register or resolve values. Equivalently to the named interface you can
132
- # use register! and resolve! to softly resolve or forcfully register values.
133
- OtherExample::REGISTRY.resolve(KeyError)
134
- # KeyError handler
135
- # => nil
110
+ Nested.registry(:developers).resolve(:frontend, :igor)
111
+ # => 'Igor'
112
+ ```
113
+
136
114
 
115
+ ### Defining specific nesting levels of a registry
116
+
117
+ Another feature of `NxtRegistry` is that you can define the nesting levels for a registry. Levels allow you to dynamically
118
+ register values within the defined levels. This means that on any level the registry will resolve to another registry and
119
+ you can register values into a deeply nested structure.
120
+
121
+ ```ruby
122
+ class Layer
123
+ extend NxtRegistry
124
+
125
+ registry :from do
126
+ level :to do
127
+ level :via
128
+ end
129
+ end
130
+ end
131
+
132
+ # On every upper level every resolve returns a registry
133
+ Layer.registry(:from) # => Registry[from]
134
+ Layer.registry(:from).resolve(:munich) # => Registry[to] -> {}
135
+ Layer.registry(:from).resolve(:amsterdam) # => Registry[to] -> {}
136
+ Layer.registry(:from).resolve(:any_key) # => Registry[to] -> {}
137
+ Layer.registry(:from).resolve(:munich, :amsterdam) # => Registry[via] -> {}
138
+
139
+ # Register a value on the bottom level
140
+ Layer.registry(:from).resolve(:munich, :amsterdam).register(:train, -> { 'train' })
141
+ # Resolve the complete path
142
+ Layer.registry(:from).resolve(:munich, :amsterdam, :train) # => 'train'
143
+ ```
144
+
145
+ For registries with multiple levels the normal syntax for registering and resolving becomes quite weird and unreadable. This is why
146
+ every registry can be accessed through it's name or a custom accessor. The above example then can be simplified as follows.
147
+
148
+ ```ruby
149
+ class Layer
150
+ extend NxtRegistry
151
+
152
+ registry :path, accessor: :from do # registry named path, can be accessed with .from(...)
153
+ level :to do
154
+ level :via
155
+ end
156
+ end
157
+ end
158
+
159
+ # Register a value
160
+ Layer.registry(:path).from(:munich).to(:amsterdam).via(:train, -> { 'train' })
161
+ # Resolve the complete path
162
+ Layer.registry(:path).from(:munich).to(:amsterdam).via(:train) # => 'train'
137
163
  ```
138
164
 
165
+ *Note that this feature is also available for registries with a single level only.*
166
+
139
167
  ### Restrict attributes to a certain set
140
168
 
141
169
  Use `attrs` to restrict which attributes can be registered on a specific level.
@@ -197,9 +225,10 @@ registry.resolve(:one)
197
225
 
198
226
  ### Transform keys
199
227
 
200
- NxtRegistry uses a plain ruby hash to store values internally. Per default all keys used are transformed with `&:to_s`.
201
- Thus you can use symbols or strings to register and resolve values. If it's not what you want, switch it off with `transform_keys false`
202
- or define your own key transformer by assigning a block to transform_keys: `transform_keys ->(key) { key.upcase }`
228
+ `NxtRegistry` uses a plain ruby hash to store values internally. Per default all keys used are transformed with `&:to_s`.
229
+ Thus you can use symbols or strings to register and resolve values. If it's not what you want, switch it off with
230
+ `transform_keys false` or define your own key transformer by assigning a block to transform_keys:
231
+ `transform_keys ->(key) { key.upcase }`
203
232
 
204
233
  ```ruby
205
234
  registry :example do
@@ -1,19 +1,44 @@
1
1
  require 'active_support/core_ext'
2
- require "nxt_registry/version"
3
- require "nxt_registry/blank"
4
- require "nxt_registry/attribute"
5
- require "nxt_registry/errors"
6
- require "nxt_registry/nested_registry_builder"
7
- require "nxt_registry/registry"
8
- require "nxt_registry/recursive_registry"
9
- require "nxt_registry/singleton"
2
+ require 'nxt_registry/version'
3
+ require 'nxt_registry/blank'
4
+ require 'nxt_registry/attribute'
5
+ require 'nxt_registry/errors'
6
+ require 'nxt_registry/registry_builder'
7
+ require 'nxt_registry/registry'
8
+ require 'nxt_registry/recursive_registry'
9
+ require 'nxt_registry/singleton'
10
10
 
11
11
  module NxtRegistry
12
12
  def registry(name, **options, &config)
13
- Registry.new(name, **options, &config)
13
+ build_registry(Registry, name, **options, &config)
14
14
  end
15
15
 
16
16
  def recursive_registry(name, **options, &config)
17
- RecursiveRegistry.new(name, **options, &config)
17
+ build_registry(RecursiveRegistry, name, **options, &config)
18
+ end
19
+
20
+ private
21
+
22
+ def build_registry(registry_class, name, **options, &config)
23
+ registry = registries.resolve(name)
24
+
25
+ if registry.present?
26
+ if registry.configured
27
+ return registry
28
+ else
29
+ raise_unconfigured_registry_accessed(name)
30
+ end
31
+ else
32
+ registry = registry_class.new(name, **options, &config)
33
+ registries.register(name, registry)
34
+ end
35
+ end
36
+
37
+ def raise_unconfigured_registry_accessed(name)
38
+ raise ArgumentError, "The registry #{name} must be configured before accessed!"
39
+ end
40
+
41
+ def registries
42
+ @registries ||= Registry.new(:registries)
18
43
  end
19
44
  end
@@ -18,7 +18,7 @@ module NxtRegistry
18
18
  attr_reader :options, :config, :level
19
19
 
20
20
  def set_nested_builder_as_default
21
- self.default = NestedRegistryBuilder.new do
21
+ self.default = RegistryBuilder.new do
22
22
  RecursiveRegistry.new("level_#{(level + 1)}", **options.merge(level: (level + 1)), &config)
23
23
  end
24
24
  end
@@ -1,40 +1,52 @@
1
1
  module NxtRegistry
2
2
  class Registry
3
3
  def initialize(name = object_id.to_s, **options, &config)
4
+ @options = options
4
5
  @name = name
5
6
  @parent = options[:parent]
6
7
  @is_leaf = true
7
8
  @namespace = build_namespace
8
9
  @config = config
9
- @options = options
10
10
  @store = {}
11
11
  @attrs = nil
12
+ @configured = false
12
13
 
13
14
  setup_defaults(options)
14
15
  configure(&config)
15
16
  end
16
17
 
17
18
  attr_reader :name
19
+ attr_accessor :configured
18
20
 
19
- def nested(name, **options, &config)
20
- # TODO: Ensure that nesting is included in defined attrs
21
+ def level(name, **options, &config)
21
22
  options = options.merge(parent: self)
22
23
 
23
- if default.is_a?(Blank)
24
+ if is_a_blank?(default)
24
25
  self.is_leaf = false
25
26
 
26
- self.default = NestedRegistryBuilder.new do
27
+ self.default = RegistryBuilder.new do
27
28
  Registry.new(name, **options, &config)
28
29
  end
29
30
 
31
+ # Call the builder once to guarantee we do not create a registry with a broken setup
30
32
  default.call
31
- elsif default.is_a?(NestedRegistryBuilder)
33
+ elsif default.is_a?(RegistryBuilder)
32
34
  raise ArgumentError, 'Multiple nestings on the same level'
33
35
  else
34
36
  raise ArgumentError, 'Default values cannot be defined on registries that nest others'
35
37
  end
36
38
  end
37
39
 
40
+ def registry(name, **options, &config)
41
+ opts = options.merge(parent: self)
42
+ register(name, Registry.new(name, **opts, &config))
43
+ end
44
+
45
+ def registry!(name, **options, &config)
46
+ opts = options.merge(parent: self)
47
+ register!(name, Registry.new(name, **opts, &config))
48
+ end
49
+
38
50
  def attr(name)
39
51
  key = transformed_key(name)
40
52
  raise KeyError, "Attribute #{key} already registered in #{namespace}" if attrs[key]
@@ -49,20 +61,40 @@ module NxtRegistry
49
61
  args.each { |name| attr(name) }
50
62
  end
51
63
 
52
- def register(key, value)
53
- __register(key, value, raise: true)
64
+ def register(key = Blank.new, value = Blank.new, **options, &block)
65
+ if block_given?
66
+ if is_a_blank?(value)
67
+ registry(key, **options, &block)
68
+ else
69
+ raise_register_argument_error
70
+ end
71
+ else
72
+ __register(key, value, raise_on_key_already_registered: true)
73
+ end
54
74
  end
55
75
 
56
- def register!(key, value)
57
- __register(key, value, raise: false)
76
+ def register!(key = Blank.new, value = Blank.new, **options, &block)
77
+ if block_given?
78
+ if is_a_blank?(value)
79
+ registry!(key, **options, &block)
80
+ else
81
+ raise_register_argument_error
82
+ end
83
+ else
84
+ __register(key, value, raise_on_key_already_registered: false)
85
+ end
58
86
  end
59
87
 
60
- def resolve(key)
61
- __resolve(key, raise: true)
88
+ def resolve!(*keys)
89
+ keys.inject(self) do |current_registry, key|
90
+ current_registry.send(:__resolve, key, raise_on_key_not_registered: true)
91
+ end
62
92
  end
63
93
 
64
- def resolve!(key)
65
- __resolve(key, raise: false)
94
+ def resolve(*keys)
95
+ keys.inject(self) do |current_registry, key|
96
+ current_registry.send(:__resolve, key, raise_on_key_not_registered: false) || break
97
+ end
66
98
  end
67
99
 
68
100
  def to_h
@@ -70,11 +102,11 @@ module NxtRegistry
70
102
  end
71
103
 
72
104
  def [](key)
73
- store[transformed_key(key)]
105
+ resolve!(key)
74
106
  end
75
107
 
76
108
  def []=(key, value)
77
- store[transformed_key(key)] = value
109
+ register(key, value)
78
110
  end
79
111
 
80
112
  def keys
@@ -97,7 +129,7 @@ module NxtRegistry
97
129
  store.fetch(transformed_key(key), *args, &block)
98
130
  end
99
131
 
100
- delegate :size, :values, :each, to: :store
132
+ delegate :size, :values, :each, :freeze, to: :store
101
133
 
102
134
  def configure(&block)
103
135
  define_accessors
@@ -111,6 +143,8 @@ module NxtRegistry
111
143
  instance_exec(&block)
112
144
  end
113
145
  end
146
+
147
+ self.configured = true
114
148
  end
115
149
 
116
150
  def to_s
@@ -121,49 +155,48 @@ module NxtRegistry
121
155
 
122
156
  private
123
157
 
124
- attr_reader :namespace, :parent, :config, :store, :options
125
- attr_accessor :is_leaf
158
+ attr_reader :namespace, :parent, :config, :store, :options, :accessor
159
+ attr_accessor :is_leaf, :interface_defined
126
160
 
127
161
  def is_leaf?
128
162
  @is_leaf
129
163
  end
130
164
 
131
- def __register(key, value, raise: true)
165
+ def __register(key, value, raise_on_key_already_registered: true)
132
166
  key = transformed_key(key)
133
167
 
134
- raise ArgumentError, 'Not allowed to register values in a registry that contains nested registries' unless is_leaf
168
+ raise ArgumentError, "Not allowed to register values in a registry that contains nested registries" unless is_leaf
135
169
  raise KeyError, "Keys are restricted to #{attrs.keys}" if attribute_not_allowed?(key)
136
170
 
137
- on_key_already_registered && on_key_already_registered.call(key) if store[key] && raise
171
+ on_key_already_registered && on_key_already_registered.call(key) if store[key] && raise_on_key_already_registered
138
172
 
139
173
  store[key] = value
140
174
  end
141
175
 
142
- def __resolve(key, raise: true)
176
+ def __resolve(key, raise_on_key_not_registered: true)
143
177
  key = transformed_key(key)
144
178
 
145
179
  value = if is_leaf?
146
- if store[key]
180
+ if store.key?(key)
147
181
  store.fetch(key)
148
182
  else
149
- if default.is_a?(Blank)
150
- return unless raise
183
+ if is_a_blank?(default)
184
+ return unless raise_on_key_not_registered
151
185
 
152
186
  on_key_not_registered && on_key_not_registered.call(key)
153
187
  else
154
- value = resolve_default
188
+ value = resolve_default(key)
155
189
  return value unless memoize
156
190
 
157
191
  store[key] ||= value
158
192
  end
159
193
  end
160
194
  else
161
- # Call nested registry builder when we are not a leaf
162
195
  store[key] ||= default.call
163
196
  end
164
197
 
165
198
  value = if value.respond_to?(:call) && call && !value.is_a?(NxtRegistry::Registry)
166
- value.call(*[value].take(value.arity))
199
+ value.call(*[key].take(value.arity))
167
200
  else
168
201
  value
169
202
  end
@@ -176,29 +209,37 @@ module NxtRegistry
176
209
  end
177
210
 
178
211
  def define_interface
179
- define_singleton_method name do |key = Blank.new, value = Blank.new|
180
- return self if key.is_a?(Blank)
212
+ return if interface_defined
213
+
214
+ raise_invalid_accessor_name(accessor) if respond_to?(accessor)
215
+ accessor_with_bang = "#{accessor}!"
216
+ raise_invalid_accessor_name(accessor_with_bang) if respond_to?(accessor_with_bang)
217
+
218
+ define_singleton_method accessor do |key = Blank.new, value = Blank.new|
219
+ return self if is_a_blank?(key)
181
220
 
182
221
  key = transformed_key(key)
183
222
 
184
- if value.is_a?(Blank)
223
+ if is_a_blank?(value)
185
224
  resolve(key)
186
225
  else
187
226
  register(key, value)
188
227
  end
189
228
  end
190
229
 
191
- define_singleton_method "#{name}!" do |key = Blank.new, value = Blank.new|
192
- return self if key.is_a?(Blank)
230
+ define_singleton_method accessor_with_bang do |key = Blank.new, value = Blank.new|
231
+ return self if is_a_blank?(key)
193
232
 
194
233
  key = transformed_key(key)
195
234
 
196
- if value.is_a?(Blank)
235
+ if is_a_blank?(value)
197
236
  resolve!(key)
198
237
  else
199
238
  register!(key, value)
200
239
  end
201
240
  end
241
+
242
+ self.interface_defined = true
202
243
  end
203
244
 
204
245
  def setup_defaults(options)
@@ -207,6 +248,7 @@ module NxtRegistry
207
248
  @call = options.fetch(:call) { true }
208
249
  @resolver = options.fetch(:resolver, false)
209
250
  @transform_keys = options.fetch(:transform_keys) { ->(key) { key.to_s } }
251
+ @accessor = options.fetch(:accessor) { name }
210
252
 
211
253
  @on_key_already_registered = options.fetch(:on_key_already_registered) { ->(key) { raise_key_already_registered_error(key) } }
212
254
  @on_key_not_registered = options.fetch(:on_key_not_registered) { ->(key) { raise_key_not_registered_error(key) } }
@@ -217,7 +259,7 @@ module NxtRegistry
217
259
  define_singleton_method attribute do |value = Blank.new, &block|
218
260
  value = block if block
219
261
 
220
- if value.is_a?(Blank)
262
+ if is_a_blank?(value)
221
263
  instance_variable_get("@#{attribute}")
222
264
  else
223
265
  instance_variable_set("@#{attribute}", value)
@@ -236,9 +278,9 @@ module NxtRegistry
236
278
  attrs.keys.exclude?(transformed_key(key))
237
279
  end
238
280
 
239
- def resolve_default
281
+ def resolve_default(key)
240
282
  if call && default.respond_to?(:call)
241
- default.call
283
+ default.arity > 0 ? default.call(key) : default.call
242
284
  else
243
285
  default
244
286
  end
@@ -255,7 +297,7 @@ module NxtRegistry
255
297
  def transformed_key(key)
256
298
  @transformed_key ||= {}
257
299
  @transformed_key[key] ||= begin
258
- if transform_keys && !key.is_a?(Blank)
300
+ if transform_keys && !is_a_blank?(key)
259
301
  transform_keys.call(key)
260
302
  else
261
303
  key
@@ -272,5 +314,17 @@ module NxtRegistry
272
314
  def build_namespace
273
315
  parent ? name.to_s.prepend("#{parent.send(:namespace)}.") : name.to_s
274
316
  end
317
+
318
+ def raise_register_argument_error
319
+ raise ArgumentError, 'Either provide a key value pair or a block to register'
320
+ end
321
+
322
+ def is_a_blank?(value)
323
+ value.is_a?(Blank)
324
+ end
325
+
326
+ def raise_invalid_accessor_name(name)
327
+ raise ArgumentError, "#{self} already implements a method named: #{name}. Please choose a different accessor name"
328
+ end
275
329
  end
276
330
  end
@@ -1,5 +1,5 @@
1
1
  module NxtRegistry
2
- class NestedRegistryBuilder < Proc
2
+ class RegistryBuilder < Proc
3
3
  def initialize(&block)
4
4
  super(&block)
5
5
  end
@@ -1,17 +1,15 @@
1
1
  module NxtRegistry
2
2
  module Singleton
3
- def self.extended(subclass)
4
- subclass.singleton_class.class_eval do
5
- default_name = (subclass.name || 'registry')
3
+ include NxtRegistry
6
4
 
7
- define_method :registry do |name = default_name, **options, &block|
8
- @registry ||= NxtRegistry::Registry.new(name, **options, &block)
9
- end
10
-
11
- delegate_missing_to :registry
5
+ def self.included(base)
6
+ base.extend(self)
7
+ end
12
8
 
13
- define_method(:instance) { registry }
14
- end
9
+ def registry(type = Registry, **options, &config)
10
+ @registry ||= build_registry(type, self.class.name, **options, &config)
15
11
  end
12
+
13
+ delegate_missing_to :registry
16
14
  end
17
15
  end
@@ -1,3 +1,3 @@
1
1
  module NxtRegistry
2
- VERSION = "0.2.1"
2
+ VERSION = "0.3.4"
3
3
  end
@@ -6,7 +6,7 @@ Gem::Specification.new do |spec|
6
6
  spec.name = "nxt_registry"
7
7
  spec.version = NxtRegistry::VERSION
8
8
  spec.authors = ["Andreas Robecke", "Nils Sommer", "Raphael Kallensee", "Lütfi Demirci"]
9
- spec.email = ["a.robecke@getsafe.de"]
9
+ spec.email = ['a.robecke@hellogetsafe.com', 'andreas@robecke.de']
10
10
 
11
11
  spec.summary = %q{nxt_registry is a simple implementation of the container pattern}
12
12
  spec.homepage = "https://github.com/nxt-insurance"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nxt_registry
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andreas Robecke
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: exe
13
13
  cert_chain: []
14
- date: 2020-08-14 00:00:00.000000000 Z
14
+ date: 2020-12-04 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: activesupport
@@ -85,7 +85,8 @@ dependencies:
85
85
  version: '0'
86
86
  description:
87
87
  email:
88
- - a.robecke@getsafe.de
88
+ - a.robecke@hellogetsafe.com
89
+ - andreas@robecke.de
89
90
  executables: []
90
91
  extensions: []
91
92
  extra_rdoc_files: []
@@ -108,9 +109,9 @@ files:
108
109
  - lib/nxt_registry/attribute.rb
109
110
  - lib/nxt_registry/blank.rb
110
111
  - lib/nxt_registry/errors.rb
111
- - lib/nxt_registry/nested_registry_builder.rb
112
112
  - lib/nxt_registry/recursive_registry.rb
113
113
  - lib/nxt_registry/registry.rb
114
+ - lib/nxt_registry/registry_builder.rb
114
115
  - lib/nxt_registry/singleton.rb
115
116
  - lib/nxt_registry/version.rb
116
117
  - nxt_registry.gemspec