convenient_service 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/LICENSE.txt +1 -1
- data/README.md +1 -1
- data/ROADMAP.md +14 -3
- data/Taskfile.yml +30 -0
- data/convenient_service.gemspec +3 -1
- data/lib/convenient_service/aliases.rb +1 -0
- data/lib/convenient_service/common/plugins/assigns_attributes_in_constructor/using_active_model_attribute_assignment/concern.rb +0 -2
- data/lib/convenient_service/common/plugins/assigns_attributes_in_constructor/using_dry_initializer/concern.rb +0 -2
- data/lib/convenient_service/core/entities/config/entities/method_middlewares/entities/container/commands/resolve_methods_middlewares_callers.rb +1 -24
- data/lib/convenient_service/dependencies.rb +7 -0
- data/lib/convenient_service/examples/dry/gemfile/dry_service/config.rb +3 -1
- data/lib/convenient_service/examples/rails/gemfile/rails_service/config.rb +3 -1
- data/lib/convenient_service/examples/standard/request_params/constants.rb +15 -0
- data/lib/convenient_service/examples/standard/request_params/entities/description.rb +40 -0
- data/lib/convenient_service/examples/standard/request_params/entities/format.rb +40 -0
- data/lib/convenient_service/examples/standard/request_params/entities/id.rb +47 -0
- data/lib/convenient_service/examples/standard/request_params/entities/logger.rb +21 -0
- data/lib/convenient_service/examples/standard/request_params/entities/request.rb +23 -0
- data/lib/convenient_service/examples/standard/request_params/entities/source.rb +40 -0
- data/lib/convenient_service/examples/standard/request_params/entities/tag.rb +40 -0
- data/lib/convenient_service/examples/standard/request_params/entities/title.rb +40 -0
- data/lib/convenient_service/examples/standard/request_params/entities.rb +11 -0
- data/lib/convenient_service/examples/standard/request_params/services/apply_default_param_values.rb +26 -0
- data/lib/convenient_service/examples/standard/request_params/services/cast_params.rb +38 -0
- data/lib/convenient_service/examples/standard/request_params/services/extract_params_from_body.rb +70 -0
- data/lib/convenient_service/examples/standard/request_params/services/extract_params_from_path.rb +62 -0
- data/lib/convenient_service/examples/standard/request_params/services/filter_out_unpermitted_params.rb +26 -0
- data/lib/convenient_service/examples/standard/request_params/services/log_request_params.rb +54 -0
- data/lib/convenient_service/examples/standard/request_params/services/merge_params.rb +26 -0
- data/lib/convenient_service/examples/standard/request_params/services/prepare.rb +65 -0
- data/lib/convenient_service/examples/standard/request_params/services/validate_casted_params.rb +94 -0
- data/lib/convenient_service/examples/standard/request_params/services/validate_uncasted_params.rb +72 -0
- data/lib/convenient_service/examples/standard/request_params/services.rb +13 -0
- data/lib/convenient_service/examples/standard/request_params/utils/array/wrap.rb +46 -0
- data/lib/convenient_service/examples/standard/request_params/utils/array.rb +21 -0
- data/lib/convenient_service/examples/standard/request_params/utils/http/request/parse_body.rb +42 -0
- data/lib/convenient_service/examples/standard/request_params/utils/http/request/parse_path.rb +40 -0
- data/lib/convenient_service/examples/standard/request_params/utils/http/request.rb +28 -0
- data/lib/convenient_service/examples/standard/request_params/utils/http.rb +3 -0
- data/lib/convenient_service/examples/standard/request_params/utils/integer/safe_parse.rb +31 -0
- data/lib/convenient_service/examples/standard/request_params/utils/integer.rb +25 -0
- data/lib/convenient_service/examples/standard/request_params/utils/json/safe_parse.rb +40 -0
- data/lib/convenient_service/examples/standard/request_params/utils/json.rb +21 -0
- data/lib/convenient_service/examples/standard/request_params/utils/object/blank.rb +34 -0
- data/lib/convenient_service/examples/standard/request_params/utils/object/present.rb +31 -0
- data/lib/convenient_service/examples/standard/request_params/utils/object.rb +26 -0
- data/lib/convenient_service/examples/standard/request_params/utils.rb +7 -0
- data/lib/convenient_service/examples/standard/request_params.rb +48 -0
- data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/commands/generate_printable_method.rb +50 -0
- data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/commands.rb +3 -0
- data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/sub_matchers/arguments/commands/apply_stub_to_track_delegations.rb +78 -0
- data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/sub_matchers/arguments/commands/generate_printable_arguments.rb +100 -0
- data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/sub_matchers/arguments/commands.rb +4 -0
- data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/sub_matchers/arguments.rb +95 -0
- data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/sub_matchers/base.rb +87 -0
- data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/sub_matchers/return_its_value.rb +129 -0
- data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/sub_matchers/with_any_arguments.rb +37 -0
- data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/sub_matchers/with_concrete_arguments.rb +37 -0
- data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/sub_matchers/without_arguments.rb +37 -0
- data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/values/base.rb +41 -0
- data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/values/with_calling_original.rb +30 -0
- data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings/values/without_calling_original.rb +30 -0
- data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings.rb +12 -0
- data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings_collection/errors.rb +57 -0
- data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/chainings_collection.rb +171 -0
- data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities/delegation.rb +79 -0
- data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher/entities.rb +5 -0
- data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities/matcher.rb +276 -0
- data/lib/convenient_service/rspec/matchers/custom/delegate_to/entities.rb +3 -0
- data/lib/convenient_service/rspec/matchers/custom/delegate_to.rb +58 -234
- data/lib/convenient_service/rspec/matchers/custom/singleton_prepend_module.rb +79 -0
- data/lib/convenient_service/rspec/matchers/custom.rb +1 -0
- data/lib/convenient_service/rspec/matchers/singleton_prepend_module.rb +13 -0
- data/lib/convenient_service/rspec/matchers.rb +2 -0
- data/lib/convenient_service/service/plugins/has_result_steps/concern.rb +25 -0
- data/lib/convenient_service/service/plugins/has_result_steps/entities/method/commands/cast_method.rb +3 -0
- data/lib/convenient_service/service/plugins/has_result_steps/entities/method/commands/cast_method_caller.rb +8 -1
- data/lib/convenient_service/service/plugins/has_result_steps/entities/method/commands/cast_method_direction.rb +3 -0
- data/lib/convenient_service/service/plugins/has_result_steps/entities/method/commands/cast_method_key.rb +8 -1
- data/lib/convenient_service/service/plugins/has_result_steps/entities/method/commands/cast_method_name.rb +9 -5
- data/lib/convenient_service/service/plugins/has_result_steps/entities/method/concern/instance_methods.rb +4 -0
- data/lib/convenient_service/service/plugins/has_result_steps/entities/method/entities/callers/base.rb +4 -0
- data/lib/convenient_service/service/plugins/has_result_steps/entities/method/entities/callers/reassignment/commands/define_method_in_container.rb +74 -0
- data/lib/convenient_service/service/plugins/has_result_steps/entities/method/entities/callers/reassignment/commands.rb +3 -0
- data/lib/convenient_service/service/plugins/has_result_steps/entities/method/entities/callers/reassignment.rb +50 -0
- data/lib/convenient_service/service/plugins/has_result_steps/entities/method/entities/callers.rb +1 -0
- data/lib/convenient_service/service/plugins/has_result_steps/entities/method/entities/values/reassignment.rb +43 -0
- data/lib/convenient_service/service/plugins/has_result_steps/entities/method/entities/values.rb +3 -0
- data/lib/convenient_service/service/plugins/has_result_steps/entities/method/entities.rb +1 -0
- data/lib/convenient_service/service/plugins/has_result_steps/entities/method/errors.rb +22 -0
- data/lib/convenient_service/service/plugins/has_result_steps/entities/step/concern/instance_methods.rb +13 -2
- data/lib/convenient_service/support/arguments/null_arguments.rb +28 -0
- data/lib/convenient_service/support/arguments.rb +87 -0
- data/lib/convenient_service/support/dependency_container/commands/assert_valid_scope.rb +32 -0
- data/lib/convenient_service/support/dependency_container/commands/import_method.rb +13 -23
- data/lib/convenient_service/support/dependency_container/commands.rb +1 -0
- data/lib/convenient_service/support/dependency_container/constants.rb +4 -2
- data/lib/convenient_service/support/dependency_container/entities/method.rb +2 -9
- data/lib/convenient_service/support/dependency_container/entities/namespace_collection.rb +0 -9
- data/lib/convenient_service/support/dependency_container/errors.rb +25 -0
- data/lib/convenient_service/support/dependency_container/export.rb +8 -0
- data/lib/convenient_service/support/dependency_container/import.rb +3 -1
- data/lib/convenient_service/support/version/null_version.rb +7 -0
- data/lib/convenient_service/support/version.rb +11 -1
- data/lib/convenient_service/support.rb +1 -0
- data/lib/convenient_service/utils/object/instance_variable_delete.rb +41 -0
- data/lib/convenient_service/utils/object/instance_variable_fetch.rb +4 -0
- data/lib/convenient_service/utils/object.rb +9 -0
- data/lib/convenient_service/utils/proc/display.rb +43 -0
- data/lib/convenient_service/utils/proc.rb +5 -0
- data/lib/convenient_service/version.rb +1 -1
- metadata +101 -4
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ConvenientService
|
4
|
+
module Service
|
5
|
+
module Plugins
|
6
|
+
module HasResultSteps
|
7
|
+
module Entities
|
8
|
+
class Method
|
9
|
+
module Entities
|
10
|
+
module Callers
|
11
|
+
class Reassignment < Callers::Base
|
12
|
+
module Commands
|
13
|
+
class DefineMethodInContainer < Support::Command
|
14
|
+
include Support::Delegate
|
15
|
+
|
16
|
+
attr_reader :method, :container, :index
|
17
|
+
|
18
|
+
delegate :key, :name, to: :method
|
19
|
+
|
20
|
+
def initialize(method:, container:, index:)
|
21
|
+
@method = method
|
22
|
+
@container = container
|
23
|
+
@index = index
|
24
|
+
end
|
25
|
+
|
26
|
+
##
|
27
|
+
# @return [Boolean]
|
28
|
+
#
|
29
|
+
def call
|
30
|
+
##
|
31
|
+
# NOTE: `prepend` is thread-safe.
|
32
|
+
#
|
33
|
+
container.klass.prepend reassigned_methods
|
34
|
+
|
35
|
+
return false if Utils::Module.instance_method_defined?(reassigned_methods, method, private: true)
|
36
|
+
|
37
|
+
<<~RUBY.tap { |code| reassigned_methods.module_eval(code, __FILE__, __LINE__ + 1) }
|
38
|
+
def #{name}
|
39
|
+
step =
|
40
|
+
steps
|
41
|
+
.select { |step| step.has_reassignment?(__method__) }
|
42
|
+
.select(&:completed?)
|
43
|
+
.last
|
44
|
+
|
45
|
+
return super unless step
|
46
|
+
|
47
|
+
key = step.reassignment(__method__).key.to_sym
|
48
|
+
|
49
|
+
step.result.data[key]
|
50
|
+
end
|
51
|
+
RUBY
|
52
|
+
|
53
|
+
true
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
##
|
59
|
+
# @return [Module]
|
60
|
+
#
|
61
|
+
def reassigned_methods
|
62
|
+
@reassigned_methods ||= Utils::Module.fetch_own_const(container.klass, :ReassignedMethods) { ::Module.new }
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "reassignment/commands"
|
4
|
+
|
5
|
+
module ConvenientService
|
6
|
+
module Service
|
7
|
+
module Plugins
|
8
|
+
module HasResultSteps
|
9
|
+
module Entities
|
10
|
+
class Method
|
11
|
+
module Entities
|
12
|
+
module Callers
|
13
|
+
class Reassignment < Callers::Base
|
14
|
+
def reassignment?(name)
|
15
|
+
##
|
16
|
+
# TODO: A better name for `object`. Wrapped object, `target`?
|
17
|
+
#
|
18
|
+
object.to_sym == name.to_sym
|
19
|
+
end
|
20
|
+
|
21
|
+
##
|
22
|
+
# TODO: Separate `in` and `out` methods?
|
23
|
+
#
|
24
|
+
def calculate_value(method)
|
25
|
+
raise Errors::CallerCanNotCalculateReassignment.new(method: method)
|
26
|
+
end
|
27
|
+
|
28
|
+
def validate_as_input_for_container!(container, method:)
|
29
|
+
raise Errors::InputMethodReassignment.new(method: method, container: container)
|
30
|
+
end
|
31
|
+
|
32
|
+
def validate_as_output_for_container!(container, method:)
|
33
|
+
##
|
34
|
+
# TODO: Raise when container has two reassignments with same name.
|
35
|
+
#
|
36
|
+
true
|
37
|
+
end
|
38
|
+
|
39
|
+
def define_output_in_container!(container, index:, method:)
|
40
|
+
Commands::DefineMethodInContainer.call(method: method, container: container, index: index)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ConvenientService
|
4
|
+
module Service
|
5
|
+
module Plugins
|
6
|
+
module HasResultSteps
|
7
|
+
module Entities
|
8
|
+
class Method
|
9
|
+
module Entities
|
10
|
+
module Values
|
11
|
+
##
|
12
|
+
# TODO: Specs.
|
13
|
+
#
|
14
|
+
class Reassignment
|
15
|
+
include Support::Delegate
|
16
|
+
|
17
|
+
attr_reader :value
|
18
|
+
|
19
|
+
delegate :to_s, :to_sym, to: :value
|
20
|
+
|
21
|
+
##
|
22
|
+
# @param value [String, Symbol] Method name to reassign.
|
23
|
+
#
|
24
|
+
def initialize(value)
|
25
|
+
@value = value
|
26
|
+
end
|
27
|
+
|
28
|
+
def ==(other)
|
29
|
+
return unless other.instance_of?(self.class)
|
30
|
+
|
31
|
+
return false if value != other.value
|
32
|
+
|
33
|
+
true
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -87,6 +87,28 @@ module ConvenientService
|
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
90
|
+
class CallerCanNotCalculateReassignment < ::ConvenientService::Error
|
91
|
+
def initialize(method:)
|
92
|
+
message = <<~TEXT
|
93
|
+
Method caller failed to calculate reassignment for `#{method.name}`.
|
94
|
+
|
95
|
+
Method callers can calculate only `in` methods, while reassignments are always `out` methods.
|
96
|
+
TEXT
|
97
|
+
|
98
|
+
super(message)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
class InputMethodReassignment < ConvenientService::Error
|
103
|
+
def initialize(method:, container:)
|
104
|
+
message = <<~TEXT
|
105
|
+
Reassignments are not allowed for `in` methods.
|
106
|
+
TEXT
|
107
|
+
|
108
|
+
super(message)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
90
112
|
class MethodIsNotInputMethod < ConvenientService::Error
|
91
113
|
def initialize(method:, container:)
|
92
114
|
message = <<~TEXT
|
@@ -50,10 +50,18 @@ module ConvenientService
|
|
50
50
|
Utils::Bool.to_bool(organizer)
|
51
51
|
end
|
52
52
|
|
53
|
+
def has_reassignment?(name)
|
54
|
+
outputs.any? { |output| output.reassignment?(name) }
|
55
|
+
end
|
56
|
+
|
53
57
|
def completed?
|
54
58
|
Utils::Bool.to_bool(@completed)
|
55
59
|
end
|
56
60
|
|
61
|
+
def reassignment(name)
|
62
|
+
outputs.find { |output| output.reassignment?(name) }
|
63
|
+
end
|
64
|
+
|
57
65
|
def params
|
58
66
|
@params ||= resolve_params
|
59
67
|
end
|
@@ -113,14 +121,17 @@ module ConvenientService
|
|
113
121
|
end
|
114
122
|
|
115
123
|
##
|
116
|
-
#
|
124
|
+
# @internal
|
125
|
+
# IMPORTANT: `service.result(**input_values)` is the reason, why services should have only kwargs as arguments.
|
117
126
|
#
|
118
127
|
def calculate_result
|
119
128
|
assert_has_organizer!
|
120
129
|
|
130
|
+
result = service.result(**input_values)
|
131
|
+
|
121
132
|
mark_as_completed!
|
122
133
|
|
123
|
-
|
134
|
+
result
|
124
135
|
end
|
125
136
|
|
126
137
|
def resolve_params
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ConvenientService
|
4
|
+
module Support
|
5
|
+
class Arguments
|
6
|
+
##
|
7
|
+
# @api private
|
8
|
+
#
|
9
|
+
class NullArguments < Support::Arguments
|
10
|
+
##
|
11
|
+
# @return [void]
|
12
|
+
#
|
13
|
+
def initialize
|
14
|
+
@args = []
|
15
|
+
@kwargs = {}
|
16
|
+
@block = nil
|
17
|
+
end
|
18
|
+
|
19
|
+
##
|
20
|
+
# @return [Boolean]
|
21
|
+
#
|
22
|
+
def null_arguments?
|
23
|
+
true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "arguments/null_arguments"
|
4
|
+
|
5
|
+
module ConvenientService
|
6
|
+
module Support
|
7
|
+
class Arguments
|
8
|
+
##
|
9
|
+
# @!attribute [r] args
|
10
|
+
# @return [Array]
|
11
|
+
#
|
12
|
+
attr_reader :args
|
13
|
+
|
14
|
+
##
|
15
|
+
# @!attribute [r] kwargs
|
16
|
+
# @return [Hash]
|
17
|
+
#
|
18
|
+
attr_reader :kwargs
|
19
|
+
|
20
|
+
##
|
21
|
+
# @!attribute [r] block
|
22
|
+
# @return [Proc]
|
23
|
+
#
|
24
|
+
attr_reader :block
|
25
|
+
|
26
|
+
##
|
27
|
+
# @param args [Array]
|
28
|
+
# @param kwargs [Hash]
|
29
|
+
# @param block [Proc]
|
30
|
+
# @return [void]
|
31
|
+
#
|
32
|
+
def initialize(*args, **kwargs, &block)
|
33
|
+
@args = args
|
34
|
+
@kwargs = kwargs
|
35
|
+
@block = block
|
36
|
+
end
|
37
|
+
|
38
|
+
class << self
|
39
|
+
##
|
40
|
+
# @return [ConvenientService::Support::Arguments::NullArguments]
|
41
|
+
#
|
42
|
+
def null_arguments
|
43
|
+
@null_arguments ||= Support::Arguments::NullArguments.new
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
##
|
48
|
+
# @return [Boolean]
|
49
|
+
#
|
50
|
+
def null_arguments?
|
51
|
+
false
|
52
|
+
end
|
53
|
+
|
54
|
+
##
|
55
|
+
# @return [Booleam]
|
56
|
+
#
|
57
|
+
def any?
|
58
|
+
return true if args.any?
|
59
|
+
return true if kwargs.any?
|
60
|
+
return true if block
|
61
|
+
|
62
|
+
false
|
63
|
+
end
|
64
|
+
|
65
|
+
##
|
66
|
+
# @return [Booleam]
|
67
|
+
#
|
68
|
+
def none?
|
69
|
+
!any?
|
70
|
+
end
|
71
|
+
|
72
|
+
##
|
73
|
+
# @param other [Object]
|
74
|
+
# @return [Boolean]
|
75
|
+
#
|
76
|
+
def ==(other)
|
77
|
+
return unless other.instance_of?(self.class)
|
78
|
+
|
79
|
+
return false if args != other.args
|
80
|
+
return false if kwargs != other.kwargs
|
81
|
+
return false if block != other.block
|
82
|
+
|
83
|
+
true
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ConvenientService
|
4
|
+
module Support
|
5
|
+
module DependencyContainer
|
6
|
+
module Commands
|
7
|
+
class AssertValidScope < Support::Command
|
8
|
+
##
|
9
|
+
# @!attribute [r] scope
|
10
|
+
# @return [Object]
|
11
|
+
#
|
12
|
+
attr_reader :scope
|
13
|
+
|
14
|
+
##
|
15
|
+
# @param scope [Object]
|
16
|
+
# @return [void]
|
17
|
+
#
|
18
|
+
def initialize(scope:)
|
19
|
+
@scope = scope
|
20
|
+
end
|
21
|
+
|
22
|
+
##
|
23
|
+
# @return [Module]
|
24
|
+
#
|
25
|
+
def call
|
26
|
+
raise Errors::InvalidScope.new(scope: scope) unless Constants::SCOPES.include?(scope)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -5,6 +5,8 @@ module ConvenientService
|
|
5
5
|
module DependencyContainer
|
6
6
|
module Commands
|
7
7
|
class ImportMethod < Support::Command
|
8
|
+
include Support::Delegate
|
9
|
+
|
8
10
|
##
|
9
11
|
# @!attribute [r] importing_module
|
10
12
|
# @return [Module]
|
@@ -12,41 +14,31 @@ module ConvenientService
|
|
12
14
|
attr_reader :importing_module
|
13
15
|
|
14
16
|
##
|
15
|
-
# @!attribute [r]
|
16
|
-
# @return [
|
17
|
+
# @!attribute [r] exported_method
|
18
|
+
# @return [ConvenientService::Support::DependencyContainer::Method]
|
17
19
|
#
|
18
|
-
attr_reader :
|
20
|
+
attr_reader :exported_method
|
19
21
|
|
20
22
|
##
|
21
|
-
# @!attribute [r]
|
22
|
-
# @return [
|
23
|
+
# @!attribute [r] prepend
|
24
|
+
# @return [Boolean]
|
23
25
|
#
|
24
|
-
attr_reader :
|
26
|
+
attr_reader :prepend
|
25
27
|
|
26
28
|
##
|
27
29
|
# @!attribute [r] scope
|
28
30
|
# @return [Symbol]
|
29
31
|
#
|
30
|
-
|
31
|
-
|
32
|
-
##
|
33
|
-
# @!attribute [r] prepend
|
34
|
-
# @return [Boolean]
|
35
|
-
#
|
36
|
-
attr_reader :prepend
|
32
|
+
delegate :scope, to: :exported_method
|
37
33
|
|
38
34
|
##
|
39
35
|
# @param importing_module [Module]
|
40
|
-
# @param
|
41
|
-
# @param method [ConvenientService::Support::DependencyContainer::Method]
|
42
|
-
# @param scope [:instance, :class]
|
36
|
+
# @param exported_method [ConvenientService::Support::DependencyContainer::Method]
|
43
37
|
# @param prepend [Boolean]
|
44
38
|
#
|
45
|
-
def initialize(importing_module:,
|
39
|
+
def initialize(importing_module:, exported_method:, prepend:)
|
46
40
|
@importing_module = importing_module
|
47
|
-
@
|
48
|
-
@method = method
|
49
|
-
@scope = scope
|
41
|
+
@exported_method = exported_method
|
50
42
|
@prepend = prepend
|
51
43
|
end
|
52
44
|
|
@@ -56,9 +48,7 @@ module ConvenientService
|
|
56
48
|
def call
|
57
49
|
import imported_scoped_methods
|
58
50
|
|
59
|
-
|
60
|
-
|
61
|
-
method
|
51
|
+
exported_method.define_in_module!(imported_scoped_methods)
|
62
52
|
end
|
63
53
|
|
64
54
|
private
|
@@ -4,8 +4,10 @@ module ConvenientService
|
|
4
4
|
module Support
|
5
5
|
module DependencyContainer
|
6
6
|
module Constants
|
7
|
-
|
8
|
-
|
7
|
+
SCOPES = [
|
8
|
+
INSTANCE_SCOPE = :instance,
|
9
|
+
CLASS_SCOPE = :class
|
10
|
+
]
|
9
11
|
|
10
12
|
DEFAULT_SCOPE = Constants::INSTANCE_SCOPE
|
11
13
|
DEFAULT_PREPEND = false
|
@@ -80,9 +80,9 @@ module ConvenientService
|
|
80
80
|
# - Same methods are redefined.
|
81
81
|
# - In contrast, same namespaces are always reused.
|
82
82
|
#
|
83
|
-
innermost_namespace.define_method(
|
83
|
+
innermost_namespace.define_method(name, &body)
|
84
84
|
|
85
|
-
|
85
|
+
self
|
86
86
|
end
|
87
87
|
|
88
88
|
##
|
@@ -101,13 +101,6 @@ module ConvenientService
|
|
101
101
|
|
102
102
|
private
|
103
103
|
|
104
|
-
##
|
105
|
-
# @return [ConvenientService::Support::DependencyContainer::Entities::Method]
|
106
|
-
#
|
107
|
-
def method
|
108
|
-
self
|
109
|
-
end
|
110
|
-
|
111
104
|
##
|
112
105
|
# @return [Array<String>]
|
113
106
|
#
|
@@ -13,15 +13,6 @@ module ConvenientService
|
|
13
13
|
@namespaces = namespaces
|
14
14
|
end
|
15
15
|
|
16
|
-
##
|
17
|
-
#
|
18
|
-
#
|
19
|
-
def define_namespace(namespace)
|
20
|
-
namespaces << namespace
|
21
|
-
|
22
|
-
define_singleton_method(namespace.name) { namespace.body.call }
|
23
|
-
end
|
24
|
-
|
25
16
|
##
|
26
17
|
# @param name [String, Symbol]
|
27
18
|
# @return [ConvenientService::Support::DependencyContainer::Entities::Namespace, nil]
|
@@ -4,6 +4,31 @@ module ConvenientService
|
|
4
4
|
module Support
|
5
5
|
module DependencyContainer
|
6
6
|
module Errors
|
7
|
+
class InvalidScope < ConvenientService::Error
|
8
|
+
##
|
9
|
+
# @param scope [Object]
|
10
|
+
# @return [void]
|
11
|
+
#
|
12
|
+
def initialize(scope:)
|
13
|
+
message = <<~TEXT
|
14
|
+
Scope `#{scope.inspect}` is NOT valid.
|
15
|
+
|
16
|
+
Valid options are #{printable_valid_scopes}.
|
17
|
+
TEXT
|
18
|
+
|
19
|
+
super(message)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
##
|
25
|
+
# @return [String]
|
26
|
+
#
|
27
|
+
def printable_valid_scopes
|
28
|
+
Constants::SCOPES.map { |scope| "`:#{scope}`" }.join(", ")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
7
32
|
class NotExportableModule < ConvenientService::Error
|
8
33
|
##
|
9
34
|
# @param mod [Module]
|
@@ -13,7 +13,15 @@ module ConvenientService
|
|
13
13
|
# @param body [Proc]
|
14
14
|
# @return [ConvenientService::Support::DependencyContainer::Entities::Method]
|
15
15
|
#
|
16
|
+
# @internal
|
17
|
+
# NOTE: `export` does NOT accept `prepend` kwarg intentionally.
|
18
|
+
# It is done to follow "the Ruby way".
|
19
|
+
# You won't ever see a module in Ruby that contains methods for `include` and `prepend` at the same time.
|
20
|
+
# So why `export` should allow to do it?
|
21
|
+
#
|
16
22
|
def export(full_name, scope: Constants::DEFAULT_SCOPE, &body)
|
23
|
+
Commands::AssertValidScope.call(scope: scope)
|
24
|
+
|
17
25
|
Entities::Method.new(full_name: full_name, scope: scope, body: body).tap { |method| exported_methods << method }
|
18
26
|
end
|
19
27
|
|
@@ -15,13 +15,15 @@ module ConvenientService
|
|
15
15
|
# @return [ConvenientService::Support::DependencyContainer::Entities::Method]
|
16
16
|
#
|
17
17
|
def import(full_name, from:, scope: Constants::DEFAULT_SCOPE, prepend: Constants::DEFAULT_PREPEND)
|
18
|
+
Commands::AssertValidScope.call(scope: scope)
|
19
|
+
|
18
20
|
raise Errors::NotExportableModule.new(mod: from) unless Utils::Module.include_module?(from, DependencyContainer::Export)
|
19
21
|
|
20
22
|
method = from.exported_methods.find_by(full_name: full_name, scope: scope)
|
21
23
|
|
22
24
|
raise Errors::NotExportedMethod.new(method_name: full_name, method_scope: scope, mod: from) unless method
|
23
25
|
|
24
|
-
Commands::ImportMethod.call(importing_module: self,
|
26
|
+
Commands::ImportMethod.call(importing_module: self, exported_method: method, prepend: prepend)
|
25
27
|
end
|
26
28
|
end
|
27
29
|
end
|
@@ -24,10 +24,17 @@ module ConvenientService
|
|
24
24
|
# @return [ConvenientService::Support::Version::NullVersion]
|
25
25
|
#
|
26
26
|
def null_version
|
27
|
-
@null_version ||= NullVersion.new
|
27
|
+
@null_version ||= Support::Version::NullVersion.new
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
+
##
|
32
|
+
# @return [Boolean]
|
33
|
+
#
|
34
|
+
def null_version?
|
35
|
+
false
|
36
|
+
end
|
37
|
+
|
31
38
|
##
|
32
39
|
# @return [Gem::Version, nil]
|
33
40
|
#
|
@@ -52,6 +59,9 @@ module ConvenientService
|
|
52
59
|
|
53
60
|
private
|
54
61
|
|
62
|
+
##
|
63
|
+
# @return [String]
|
64
|
+
#
|
55
65
|
attr_reader :value
|
56
66
|
|
57
67
|
##
|
@@ -4,6 +4,7 @@ require_relative "support/not_passed"
|
|
4
4
|
require_relative "support/concern"
|
5
5
|
|
6
6
|
require_relative "support/abstract_method"
|
7
|
+
require_relative "support/arguments"
|
7
8
|
require_relative "support/cache"
|
8
9
|
require_relative "support/castable"
|
9
10
|
require_relative "support/command"
|