hexx 5.4.0 → 6.0.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/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
|