hexx 5.4.0 → 6.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.rdoc +211 -81
- data/Rakefile +1 -2
- data/lib/hexx.rb +1 -0
- data/lib/hexx/{models.rb → coercible.rb} +10 -12
- data/lib/hexx/configurable.rb +101 -0
- data/lib/hexx/dependable.rb +51 -0
- data/lib/hexx/helpers/base.rb +111 -0
- data/lib/hexx/helpers/coersion.rb +82 -0
- data/lib/hexx/helpers/dependency.rb +87 -0
- data/lib/hexx/helpers/module_dependency.rb +57 -0
- data/lib/hexx/helpers/parameter.rb +40 -0
- data/lib/hexx/service.rb +96 -51
- data/lib/hexx/service/with_callbacks.rb +6 -7
- data/lib/hexx/version.rb +1 -1
- data/spec/hexx/coercible_spec.rb +56 -0
- data/spec/hexx/{dependencies_spec.rb → configurable_spec.rb} +7 -20
- data/spec/hexx/dependable_spec.rb +125 -0
- data/spec/hexx/service_spec.rb +24 -16
- metadata +16 -10
- data/lib/hexx/dependencies.rb +0 -182
- data/lib/hexx/models/base_coercer.rb +0 -44
- data/lib/hexx/service/parameters.rb +0 -81
- data/spec/hexx/models_spec.rb +0 -40
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2e8768af29b2a06a1eec7ae917896144373edf4e
|
4
|
+
data.tar.gz: 33b14d58fda376b285b3674a69efc05fcf0ad3d9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 688a02c4e5b617233bd222451e44580e4974e0ba93a54ae6532ba160a01aa37c4bbd67d0db3ee12b22a19567502947a6b7cb29cf79883a23b476093a1e8f67c3
|
7
|
+
data.tar.gz: 32504f32691f79843f70416690f75c70f9679e8517659d3cec6ff62029365341673d017a1555e1de2137e1b80ca314a9e9fec6cd8917a2de1f9801100f089b31
|
data/README.rdoc
CHANGED
@@ -7,16 +7,25 @@
|
|
7
7
|
{<img src="http://img.shields.io/coveralls/nepalez/hexx.svg?style=flat" alt="Coverage Status" />}[https://coveralls.io/r/nepalez/hexx]
|
8
8
|
{<img src="http://img.shields.io/badge/license-MIT-blue.svg?style=flat" alt="License" />}[https://github.com/nepalez/hexx/blob/master/LICENSE.rdoc]
|
9
9
|
|
10
|
-
The
|
11
|
-
domain models (entities).
|
10
|
+
The base library for domain models.
|
12
11
|
|
13
|
-
|
14
|
-
* +Service+ base class for decoupling a domain business logics from a controller
|
15
|
-
* +Models+ module for extending domain models.
|
12
|
+
== API
|
16
13
|
|
17
|
-
|
18
|
-
|
19
|
-
|
14
|
+
Includes classes and modules as below:
|
15
|
+
<tt>Hexx::Service</tt>:: The base class for service objects.
|
16
|
+
<tt>Hexx::Service::Message</tt>:: The message provided by service objects.
|
17
|
+
<tt>Hexx::Null</tt>:: The Null object.
|
18
|
+
<tt>Hexx::Coercible</tt>:: The module that makes model attributes coercible.
|
19
|
+
<tt>Hexx::Configurable</tt>:: The module to convert a core domain module to the
|
20
|
+
dependency injection framework.
|
21
|
+
<tt>Hexx::Dependable</tt>:: The module provides +depends_on+ class helper methodto
|
22
|
+
to implement the setter dependency injection.
|
23
|
+
|
24
|
+
The module is expected to be used in PORO domains for Ruby MRI 2.1+.
|
25
|
+
|
26
|
+
For usage in active record bases domains consider the
|
27
|
+
{ hexx-active_record }[https://github.com/nepalez/hexx-active_record]
|
28
|
+
gem extension.
|
20
29
|
|
21
30
|
== Installation
|
22
31
|
|
@@ -32,47 +41,172 @@ Or install it yourself as:
|
|
32
41
|
|
33
42
|
$ gem install hexx
|
34
43
|
|
35
|
-
==
|
44
|
+
== Usage
|
45
|
+
|
46
|
+
=== Hexx::Configurable
|
47
|
+
|
48
|
+
Adds the +configure+ and +depends_on+ helpers to the module to convert it
|
49
|
+
to the {dependency injection container}[http://en.m.wikipedia.org/wiki/Dependency_injection].
|
50
|
+
|
51
|
+
Extend the base class of the gem and declare the module dependencies from
|
52
|
+
outer classes and modules with the +depend_on+ helper:
|
53
|
+
|
54
|
+
# lib/my_gem.rb
|
55
|
+
module MyGem
|
56
|
+
extend Hexx::Configurable
|
57
|
+
|
58
|
+
depend_on :get_item, :add_item
|
59
|
+
end
|
60
|
+
|
61
|
+
Inject the dependencies in the gem config with the +configure+ wrapper:
|
62
|
+
|
63
|
+
# config/dependencies.rb
|
64
|
+
MyGem.configure do |c|
|
65
|
+
c.get_item = OuterModule::Services::Get
|
66
|
+
c.add_item = OuterModule::Services::Add
|
67
|
+
end
|
68
|
+
|
69
|
+
Use the dependencies somewhere inside the code of the gem:
|
70
|
+
|
71
|
+
MyGem.get_item # => OuterModule::Services::Get
|
72
|
+
|
73
|
+
=== Hexx::Coercible
|
74
|
+
|
75
|
+
Adds the +attr_coerced+ class helper method to the PORO model.
|
76
|
+
|
77
|
+
Provide a value object that accepts <tt>0..1</tt> arguments.
|
78
|
+
|
79
|
+
# app/attributes/coercer.rb
|
80
|
+
class Coercer < MultiByte::Chars
|
81
|
+
def self.new(source = nil)
|
82
|
+
return unless source
|
83
|
+
end
|
84
|
+
|
85
|
+
def initialize(source)
|
86
|
+
# ...
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
Extend the model with a +Coercible+ module and declare its attributes
|
91
|
+
with the +attr_coerced+ helper.
|
92
|
+
|
93
|
+
# app/models/some_model.rb
|
94
|
+
class SomeModel
|
95
|
+
extend Hexx::Coercible
|
96
|
+
|
97
|
+
attr_coerced :name, type: Coercer
|
98
|
+
end
|
99
|
+
|
100
|
+
Both the getter and setter will return the coerced value, provided by
|
101
|
+
the +Coercer+ class.
|
102
|
+
|
103
|
+
object = SomeModel.new name: "Ivo"
|
104
|
+
object.name
|
105
|
+
# #<Coercer @wrapped_string="Ivo" >
|
106
|
+
|
107
|
+
Be careful when designing a coercer class. Its constructor should accept both
|
108
|
+
the raw value ("Ivo") and the coerced one (#<Coercer @wrapped_string = "Ivo">).
|
109
|
+
This is needed because the coercer works twofold - it coerces both the
|
110
|
+
setter and getter. The getter coercer will take the coerced value.
|
111
|
+
|
112
|
+
This feature is added for comparison with +ActiveRecord+ attributes coersion
|
113
|
+
where the getter is given with stored raw values (a string etc.)
|
36
114
|
|
37
|
-
|
115
|
+
*Note*: The coercer from +hexx+ gem itself won't work for +ActiveRecord+ models.
|
116
|
+
Use the +hexx-active_record+ gem instead. The gem extends the +Coercible+ model
|
117
|
+
so that the +attr_coerced+ reloads +ActiveRecord+ attributes properly.
|
38
118
|
|
39
|
-
|
40
|
-
* Delivery mechanism _controllers_ (such as Rails framework).
|
119
|
+
=== Hexx::Service
|
41
120
|
|
42
|
-
|
43
|
-
*Observer* (Listener) pattern via { Wisper }[https://github.com/krisleech/wisper]
|
44
|
-
gem.
|
121
|
+
Inherit services from the <tt>Hexx::Service</tt> class.
|
45
122
|
|
46
|
-
|
47
|
-
{ wisper gem wiki }[https://github.com/krisleech/wisper/wiki].
|
123
|
+
The class implements a set of patterns:
|
48
124
|
|
49
|
-
|
125
|
+
* The {Service object pattern}[http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/] used to decouple business logics from both the models and web delivery mechanism (such as +Rails+).
|
126
|
+
* The {Observer pattern}[http://reefpoints.dockyard.com/2013/08/20/design-patterns-observer-pattern.html] to follow the {Tell, don't ask}[http://martinfowler.com/bliki/TellDontAsk.html] design princible.
|
127
|
+
The pattern is implemented with the help of {wisper}[http://www.github.com/krisleech/wisper] gem by Kris Leech.
|
128
|
+
* The {Setter-based dependency injection}[http://brandonhilkert.com/blog/a-ruby-refactor-exploring-dependency-injection-options/] to decouple the service from another services it uses.
|
50
129
|
|
51
130
|
A typical service object is shown below:
|
52
131
|
|
132
|
+
# app/services/add_item.rb
|
53
133
|
require 'hexx'
|
54
|
-
|
55
134
|
class AddItem < Hexx::Service
|
56
135
|
|
57
|
-
#
|
136
|
+
# Injects the dependency from the service for getting an item.
|
137
|
+
# Provides default implementation for the dependency, that could be
|
138
|
+
# redefined later (in a test suite etc.).
|
139
|
+
depends_on :get_item, default: GetItem
|
140
|
+
|
141
|
+
# Whitelists parameters and defines corresponding attributes.
|
142
|
+
# For example, the #name attribute is avalable.
|
58
143
|
allow_params :name
|
59
144
|
|
60
|
-
#
|
145
|
+
# Defines some validation using ActiveModel::Validations helpers.
|
61
146
|
validate :name, presence: true
|
62
147
|
|
63
|
-
#
|
148
|
+
# Runs a service
|
64
149
|
def run
|
65
|
-
|
66
|
-
|
67
|
-
|
150
|
+
run!
|
151
|
+
rescue Found
|
152
|
+
# Publishes notification in case the item exists.
|
153
|
+
publish :found, item
|
154
|
+
rescue => err
|
68
155
|
publish :error, err.messages
|
69
156
|
else
|
70
|
-
|
157
|
+
# The notification to be published if the #run! raises nothing.
|
158
|
+
publish :added, item
|
159
|
+
end
|
160
|
+
|
161
|
+
private
|
162
|
+
|
163
|
+
attr_accessor :item
|
164
|
+
|
165
|
+
# Errors to be raised by the #run! method call and captured in a #run.
|
166
|
+
class Found < StandardError; end
|
167
|
+
|
168
|
+
# The sequence of the service steps. Any step can raise error to
|
169
|
+
# be rescued in #run with publishing a corresponding notification.
|
170
|
+
def run!
|
171
|
+
find_item
|
172
|
+
add_item
|
71
173
|
end
|
72
|
-
end
|
73
174
|
|
74
|
-
|
175
|
+
def find_item
|
176
|
+
# The method runs another service and listens to its notifications
|
177
|
+
# via private callback methods available to that service only.
|
178
|
+
# The callback names should start from given prefix (:on_item_).
|
179
|
+
run_service get_item, :on_item, name: name
|
180
|
+
end
|
181
|
+
|
182
|
+
# The callback to listen to :found notification of the 'get_item' service.
|
183
|
+
def on_item_found(item, *)
|
184
|
+
@item = item
|
185
|
+
# Adds the Hexx::Message object of type "error" to the +messages+ array.
|
186
|
+
# The :not_found key will be translated in context of current service:
|
187
|
+
# {locale}.activemodule.messages.models.add_item.not_found
|
188
|
+
add_message "error", :not_found
|
189
|
+
fail Found # goes to publishing a result
|
190
|
+
end
|
191
|
+
|
192
|
+
# The callback to listen to :error notification of the 'get_item' service.
|
193
|
+
# that is expected to publish a list of error messages.
|
194
|
+
def on_item_error(*, messages)
|
195
|
+
# The helper raises Hexx::Service::Invalid exception where the messages
|
196
|
+
# are added to. The exception will be rescued by the #run method.
|
197
|
+
on_error(messages)
|
198
|
+
end
|
199
|
+
|
200
|
+
def add_item
|
201
|
+
# The escape re-raises any error as the Hexx::Service::Invalid
|
202
|
+
# with the array of Hexx::Service::Message messages.
|
203
|
+
escape { @item = Item.create! name: name }
|
204
|
+
end
|
205
|
+
end
|
75
206
|
|
207
|
+
A typical usage of the service (in a Rails controller):
|
208
|
+
|
209
|
+
# app/controllers/items_controller.rb
|
76
210
|
class ItemsController < ActionController::Base
|
77
211
|
|
78
212
|
# Creates an item with given name
|
@@ -88,87 +222,83 @@ Usage of the service (in a Rails controller):
|
|
88
222
|
render "created", status: 201
|
89
223
|
end
|
90
224
|
|
225
|
+
# Responds with 304 (not changed)
|
226
|
+
def on_found(*)
|
227
|
+
render nothing: true, status: 304
|
228
|
+
end
|
229
|
+
|
91
230
|
# Publishes an error messages
|
92
231
|
def on_error(messages)
|
93
232
|
@messages = messages
|
94
|
-
render "error"
|
233
|
+
render "error", status: 422
|
95
234
|
end
|
96
235
|
end
|
97
236
|
|
98
237
|
The controller knows nothing about the action itself. It only needs to
|
99
|
-
|
238
|
+
send the request to a corresponding service and sort out the notifications.
|
100
239
|
|
101
|
-
|
240
|
+
=== Hexx::Service::Message
|
102
241
|
|
103
|
-
|
104
|
-
* both +on_success+ and +on_created+ listens to services and report their
|
105
|
-
results back to client.
|
242
|
+
The messages published by the service has two attributes: +type+ and +text+.
|
106
243
|
|
107
|
-
|
244
|
+
message = Hexx::Service::Message.new type: :error, text: "some error message"
|
245
|
+
message.type # => "error"
|
246
|
+
message.text # => "some error message"
|
108
247
|
|
109
|
-
|
110
|
-
(entities). This allows coercion of attributes with +attr_coerced+ helper:
|
248
|
+
Inside a service use the +add_message+ to add message to the +messages+ array:
|
111
249
|
|
112
|
-
|
113
|
-
|
114
|
-
attr_coerced :name, type: ActiveSupport::Multibyte::Chars
|
115
|
-
end
|
250
|
+
add_message "error", "text"
|
251
|
+
messages # => [#<Hexx::Service::Message @type="error", @text="text" >]
|
116
252
|
|
117
|
-
|
118
|
-
|
119
|
-
user.name
|
120
|
-
# => "Ivan"
|
121
|
-
|
122
|
-
user.name.class
|
123
|
-
# => ActiveSupport::Multibyte::Chars
|
253
|
+
=== Hexx::Null
|
124
254
|
|
125
|
-
The
|
126
|
-
preparation:
|
255
|
+
The class implements the {Null object}[http://robots.thoughtbot.com/rails-refactoring-example-introduce-null-object] pattern. The object:
|
127
256
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
end
|
132
|
-
end
|
257
|
+
* responds like +nil+ to +<=>+, +eq?+, +nil?+, +false?+, +true?+, +to_s+,
|
258
|
+
+to_i+, +to_f+, +to_c+, +to_r+, +to_nil+
|
259
|
+
* responds with +self+ to any other method call
|
133
260
|
|
134
|
-
|
135
|
-
extend Hexx::Models
|
136
|
-
attr_coerced :name, type: StrippedString
|
137
|
-
end
|
261
|
+
Providing {this problem}[http://devblog.avdi.org/2011/05/30/null-objects-and-falsiness/], use double bang in logical expressions:
|
138
262
|
|
139
|
-
|
140
|
-
|
263
|
+
# Though:
|
264
|
+
Hexx::Null && true # => true
|
265
|
+
|
266
|
+
# But:
|
267
|
+
!!Hexx::Null && true # => false
|
141
268
|
|
142
|
-
|
269
|
+
=== Hexx::Dependable
|
143
270
|
|
144
|
-
|
145
|
-
dependency
|
271
|
+
This module is a part of <tt>Hexx::Service</tt> that provides
|
272
|
+
setter dependency declaration +depends_on+.
|
146
273
|
|
147
|
-
|
274
|
+
Extend the class and declare the dependency with optional default
|
275
|
+
implementation:
|
148
276
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
depends_on :
|
277
|
+
class MyClass
|
278
|
+
extend Hexx::Dependable
|
279
|
+
|
280
|
+
depends_on :another_class, default: AhotherClass
|
281
|
+
depends_on :one_more_class
|
153
282
|
end
|
154
283
|
|
155
|
-
|
284
|
+
Now the dependency can be injected afterwards:
|
156
285
|
|
157
|
-
|
158
|
-
MyGem.configure do |config|
|
159
|
-
config.get_item = AnotherGem::Services::Get # as a constant
|
160
|
-
config.add_item = "AnotherGem::Services::Add" # as a name of a constant
|
161
|
-
end
|
286
|
+
object = MyClass
|
162
287
|
|
163
|
-
|
288
|
+
# The default implementation
|
289
|
+
object.another_class # => AnotherClass
|
164
290
|
|
165
|
-
|
166
|
-
|
291
|
+
# Inject another implementation
|
292
|
+
object.another_class = NewClass
|
293
|
+
object.another_class # => NewClass
|
167
294
|
|
168
|
-
|
295
|
+
# Reset it to default
|
296
|
+
object.another_class = nil
|
297
|
+
object.another_class # => AnotherClass
|
169
298
|
|
170
|
-
|
171
|
-
|
299
|
+
# Implementation is needed
|
300
|
+
object.one_more_class
|
301
|
+
# fails with a NotImplementedError
|
172
302
|
|
173
303
|
== License
|
174
304
|
|
data/Rakefile
CHANGED
@@ -19,6 +19,5 @@ task :check do
|
|
19
19
|
system "coveralls report"
|
20
20
|
system "rubocop"
|
21
21
|
system "inch --pedantic"
|
22
|
-
system "metric_fu --no-cane --no-
|
23
|
-
"--no-hotspots --no-reek"
|
22
|
+
system "metric_fu --no-cane --no-saikuro --no-roodi --no-hotspots --no-stats"
|
24
23
|
end
|
data/lib/hexx.rb
CHANGED
@@ -10,7 +10,7 @@ module Hexx
|
|
10
10
|
# require_relative "attributes/string"
|
11
11
|
#
|
12
12
|
# class User
|
13
|
-
# extend Hexx::
|
13
|
+
# extend Hexx::Coercible
|
14
14
|
# attr_coerced :name, type: ActiveSupport::Multibyte::Chars
|
15
15
|
# end
|
16
16
|
#
|
@@ -18,26 +18,24 @@ module Hexx
|
|
18
18
|
# user = User.new name: "Иоанн"
|
19
19
|
# user.name
|
20
20
|
# # => #<ActiveSupport::Multibyte::Chars @wrapped_string = "Иоанн">
|
21
|
-
module
|
21
|
+
module Coercible
|
22
22
|
|
23
23
|
private
|
24
24
|
|
25
|
+
# @api hide
|
26
|
+
def self.extended(klass)
|
27
|
+
klass.send :extend, Configurable
|
28
|
+
klass.send :depends_on, :coersion, default: Helpers::Coersion
|
29
|
+
end
|
30
|
+
|
25
31
|
# @!method attr_coerced(*names, options)
|
26
32
|
# Coerced the attribute(s) with given type.
|
27
|
-
# @example (see Hexx::
|
33
|
+
# @example (see Hexx::Coercible)
|
28
34
|
# @param [Array<Symbol, String>] names The list of attributes to be coerced.
|
29
35
|
# @param [Hash] options The coersion options.
|
30
36
|
# @option options [Class] :type The class for coersion.
|
31
37
|
def attr_coerced(*names, type:)
|
32
|
-
names.each { |name|
|
33
|
-
end
|
34
|
-
|
35
|
-
# @api hide
|
36
|
-
# Applied coercer for attributes.
|
37
|
-
# @note The method is reloaded in the 'hexx-active_record' gem to allow
|
38
|
-
# coersion of ActiveRecord models' attributes.
|
39
|
-
def coercer
|
40
|
-
@coercer ||= BaseCoercer
|
38
|
+
names.flatten.each { |name| coersion.add self, name, type }
|
41
39
|
end
|
42
40
|
end
|
43
41
|
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Hexx
|
4
|
+
|
5
|
+
# Contains methods to declare and inject module dependencies.
|
6
|
+
#
|
7
|
+
# Allows to provide DJ framework for the gem.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# # Declare the dependencies for the gem root module
|
11
|
+
#
|
12
|
+
# # lib/my_gem.rb
|
13
|
+
# module MyGem
|
14
|
+
# extend Hexx::Configurable
|
15
|
+
# self.depends_on :get_item, :add_item
|
16
|
+
# self.depends_on :delete_item, default: DeleteItem
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# # Inject dependencies (as a constant or its name)
|
20
|
+
#
|
21
|
+
# # config/my_gem.rb
|
22
|
+
# MyGem.configure do |config|
|
23
|
+
# config.get_item = AnotherGem::Services::Get
|
24
|
+
# config.add_item
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# # Use dependency in the module code (models, services, etc.)
|
28
|
+
# # When the dependency hasn't been set, fails with +NotImplementedError+
|
29
|
+
#
|
30
|
+
# MyGem.get_item # => AnotherGem::Services::Get
|
31
|
+
# MyGem.get_item # => DeleteItem
|
32
|
+
# MyGem.add_item # fails with a NotImplementedError
|
33
|
+
module Configurable
|
34
|
+
|
35
|
+
# Yields a block and gives it self
|
36
|
+
#
|
37
|
+
# @example
|
38
|
+
# module MyGem
|
39
|
+
# extend Hexx::Configurable
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
# MyGem.configure do |config|
|
43
|
+
# c # => MyGem
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
# @yield The block.
|
47
|
+
# @yieldparam [Hexx::Configurable] +self+.
|
48
|
+
def configure
|
49
|
+
yield(self)
|
50
|
+
end
|
51
|
+
|
52
|
+
# @!method depends_on(*names, options)
|
53
|
+
# Declares a dependency getter and setter.
|
54
|
+
#
|
55
|
+
# @example
|
56
|
+
# module MyGem
|
57
|
+
# extend Hexx::Configurable
|
58
|
+
# self.depends_on :some_class
|
59
|
+
# end
|
60
|
+
#
|
61
|
+
# MyGem.some_class = String
|
62
|
+
# # => "String"
|
63
|
+
# MyGem.some_class # => String
|
64
|
+
#
|
65
|
+
# MyGem.some_class = "String"
|
66
|
+
# # => "String"
|
67
|
+
# MyGem.some_class # => String
|
68
|
+
#
|
69
|
+
# MyGem.some_class = :String
|
70
|
+
# # => "String"
|
71
|
+
# MyGem.some_class # => String
|
72
|
+
#
|
73
|
+
# @example Dependencies can be declared by a plain list of names
|
74
|
+
# module MyGem
|
75
|
+
# extend Hexx::Configurable
|
76
|
+
# self.depends_on :some_class, "another_class"
|
77
|
+
# end
|
78
|
+
#
|
79
|
+
# @example Dependencies can be declared by an array of names
|
80
|
+
# module MyGem
|
81
|
+
# extend Hexx::Configurable
|
82
|
+
# self.depends_on %w(some_class another_class)
|
83
|
+
# end
|
84
|
+
#
|
85
|
+
# @example A dependency can have default implementation
|
86
|
+
# module MyGem
|
87
|
+
# extend Hexx::Configurable
|
88
|
+
# self.depends_on :item, default: Item
|
89
|
+
# end
|
90
|
+
#
|
91
|
+
# @param [Array<String, Symbol>] names The list of names for dependencies.
|
92
|
+
# @param [Hash] options The list of options for dependency declaration.
|
93
|
+
# @option options [Module, nil] :default (nil) The default implementation
|
94
|
+
# for the dependency.
|
95
|
+
def depends_on(*names, default: nil)
|
96
|
+
names.flatten.each do |name|
|
97
|
+
Helpers::ModuleDependency.add self, name, default
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|