convenient_service 0.4.0 → 0.5.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 +7 -0
- data/convenient_service.gemspec +1 -1
- data/lib/convenient_service/aliases.rb +5 -0
- data/lib/convenient_service/support/dependency_container/commands/create_methods_module.rb +27 -0
- data/lib/convenient_service/support/dependency_container/commands/import_method.rb +111 -0
- data/lib/convenient_service/support/dependency_container/commands.rb +4 -0
- data/lib/convenient_service/support/dependency_container/constants.rb +15 -0
- data/lib/convenient_service/support/dependency_container/entities/method.rb +121 -0
- data/lib/convenient_service/support/dependency_container/entities/method_collection.rb +98 -0
- data/lib/convenient_service/support/dependency_container/entities/namespace.rb +69 -0
- data/lib/convenient_service/support/dependency_container/entities/namespace_collection.rb +103 -0
- data/lib/convenient_service/support/dependency_container/entities.rb +6 -0
- data/lib/convenient_service/support/dependency_container/errors.rb +49 -0
- data/lib/convenient_service/support/dependency_container/export.rb +30 -0
- data/lib/convenient_service/support/dependency_container/import.rb +30 -0
- data/lib/convenient_service/support/dependency_container.rb +9 -0
- data/lib/convenient_service/support/not_passed.rb +7 -0
- data/lib/convenient_service/support.rb +2 -0
- data/lib/convenient_service/utils/module/fetch_own_const.rb +88 -0
- data/lib/convenient_service/utils/module/include_module.rb +38 -0
- data/lib/convenient_service/utils/module.rb +10 -0
- data/lib/convenient_service/utils/proc/conjunct.rb +1 -1
- data/lib/convenient_service/utils/string/split.rb +41 -0
- data/lib/convenient_service/utils/string.rb +5 -0
- data/lib/convenient_service/version.rb +1 -1
- data/lib/convenient_service.rb +6 -0
- metadata +24 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7655bb52a95f02a3f973c4f26e8e881ebf2dec66e056de3e085515b8e1c9b8f9
|
4
|
+
data.tar.gz: 440d3e574c167e88ca942e98eb022665faf918933d20789d4acc50f90bd0e9e8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2f76c7d18d8dbe51157e07c575718383148fc070cd85705450f9ea7d5bd4c3837d459b1da3125c4a1eb6188d14ce5e5d10c1b501104949f6c609e6a0f724e820
|
7
|
+
data.tar.gz: fb0f1e875261f71a01fefba836b45e6c8995ea94f9aa906050f9bebdf5b4690bafda699c624a9405cec65c14928ba1956d6c3a193f434ab471ceceb4635baef6
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [0.5.0](https://github.com/marian13/convenient_service/compare/v0.4.0...v0.5.0) (2023-01-19)
|
4
|
+
|
5
|
+
|
6
|
+
### Features
|
7
|
+
|
8
|
+
* **dependency_container:** introduce dependency containers ([7e2dd90](https://github.com/marian13/convenient_service/commit/7e2dd9072a4b8815ac74755b4fa2c3b66a093115), [aef8ac0](https://github.com/marian13/convenient_service/commit/aef8ac0ba7fdfdd968fae6e115bb9540bca28ec4))
|
9
|
+
|
3
10
|
## [0.4.0](https://github.com/marian13/convenient_service/compare/v0.3.1...v0.4.0) (2023-01-03)
|
4
11
|
|
5
12
|
|
data/convenient_service.gemspec
CHANGED
@@ -41,7 +41,7 @@ Gem::Specification.new do |spec|
|
|
41
41
|
spec.add_development_dependency "rerun"
|
42
42
|
spec.add_development_dependency "rouge"
|
43
43
|
spec.add_development_dependency "rspec", "~> 3.0"
|
44
|
-
spec.add_development_dependency "rubocop"
|
44
|
+
spec.add_development_dependency "rubocop", "~> 1.40.0"
|
45
45
|
spec.add_development_dependency "rubocop-rspec"
|
46
46
|
spec.add_development_dependency "tty-prompt"
|
47
47
|
spec.add_development_dependency "standard"
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ConvenientService
|
4
|
+
module Support
|
5
|
+
module DependencyContainer
|
6
|
+
module Commands
|
7
|
+
class CreateMethodsModule < Support::Command
|
8
|
+
##
|
9
|
+
# @return [Module]
|
10
|
+
#
|
11
|
+
def call
|
12
|
+
::Module.new do
|
13
|
+
class << self
|
14
|
+
##
|
15
|
+
# @return namespaces [ConvenientService::Support::DependencyContainer::Entities::NamespaceCollection]
|
16
|
+
#
|
17
|
+
def namespaces
|
18
|
+
@namespaces ||= Entities::NamespaceCollection.new
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ConvenientService
|
4
|
+
module Support
|
5
|
+
module DependencyContainer
|
6
|
+
module Commands
|
7
|
+
class ImportMethod < Support::Command
|
8
|
+
##
|
9
|
+
# @!attribute [r] importing_module
|
10
|
+
# @return [Module]
|
11
|
+
#
|
12
|
+
attr_reader :importing_module
|
13
|
+
|
14
|
+
##
|
15
|
+
# @!attribute [r] exporting_module
|
16
|
+
# @return [Module]
|
17
|
+
#
|
18
|
+
attr_reader :exporting_module
|
19
|
+
|
20
|
+
##
|
21
|
+
# @!attribute [r] method
|
22
|
+
# @return [ConvenientService::Support::DependencyContainer::Method]
|
23
|
+
#
|
24
|
+
attr_reader :method
|
25
|
+
|
26
|
+
##
|
27
|
+
# @!attribute [r] scope
|
28
|
+
# @return [Symbol]
|
29
|
+
#
|
30
|
+
attr_reader :scope
|
31
|
+
|
32
|
+
##
|
33
|
+
# @!attribute [r] prepend
|
34
|
+
# @return [Boolean]
|
35
|
+
#
|
36
|
+
attr_reader :prepend
|
37
|
+
|
38
|
+
##
|
39
|
+
# @param importing_module [Module]
|
40
|
+
# @param exporting_module [Module]
|
41
|
+
# @param method [ConvenientService::Support::DependencyContainer::Method]
|
42
|
+
# @param scope [:instance, :class]
|
43
|
+
# @param prepend [Boolean]
|
44
|
+
#
|
45
|
+
def initialize(importing_module:, exporting_module:, method:, scope:, prepend:)
|
46
|
+
@importing_module = importing_module
|
47
|
+
@exporting_module = exporting_module
|
48
|
+
@method = method
|
49
|
+
@scope = scope
|
50
|
+
@prepend = prepend
|
51
|
+
end
|
52
|
+
|
53
|
+
##
|
54
|
+
# @return [ConvenientService::Support::DependencyContainer::Method]
|
55
|
+
#
|
56
|
+
def call
|
57
|
+
import imported_scoped_methods
|
58
|
+
|
59
|
+
method.define_in_module!(imported_scoped_methods)
|
60
|
+
|
61
|
+
method
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
##
|
67
|
+
# @return [Module]
|
68
|
+
#
|
69
|
+
def imported_scoped_methods
|
70
|
+
@imported_scoped_methods ||= Utils::Module.fetch_own_const(importing_module, :"Imported#{imported_prefix}#{scoped_prefix}Methods") { Commands::CreateMethodsModule.call }
|
71
|
+
end
|
72
|
+
|
73
|
+
##
|
74
|
+
# @return [String]
|
75
|
+
#
|
76
|
+
def imported_prefix
|
77
|
+
prepend ? "Prepended" : "Included"
|
78
|
+
end
|
79
|
+
|
80
|
+
##
|
81
|
+
# @return [String]
|
82
|
+
#
|
83
|
+
def scoped_prefix
|
84
|
+
case scope
|
85
|
+
when Constants::INSTANCE_SCOPE then "Instance"
|
86
|
+
when Constants::CLASS_SCOPE then "Class"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
##
|
91
|
+
# @return [Module, Class]
|
92
|
+
#
|
93
|
+
def importer
|
94
|
+
case scope
|
95
|
+
when Constants::INSTANCE_SCOPE then importing_module
|
96
|
+
when Constants::CLASS_SCOPE then importing_module.singleton_class
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
##
|
101
|
+
# @param mod [Module]
|
102
|
+
# @return [Module]
|
103
|
+
#
|
104
|
+
def import(mod)
|
105
|
+
prepend ? importer.prepend(mod) : importer.include(mod)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ConvenientService
|
4
|
+
module Support
|
5
|
+
module DependencyContainer
|
6
|
+
module Constants
|
7
|
+
INSTANCE_SCOPE = :instance
|
8
|
+
CLASS_SCOPE = :class
|
9
|
+
|
10
|
+
DEFAULT_SCOPE = Constants::INSTANCE_SCOPE
|
11
|
+
DEFAULT_PREPEND = false
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ConvenientService
|
4
|
+
module Support
|
5
|
+
module DependencyContainer
|
6
|
+
module Entities
|
7
|
+
class Method
|
8
|
+
##
|
9
|
+
# @!attribute [r] full_name
|
10
|
+
# @return [String, Symbol]
|
11
|
+
#
|
12
|
+
attr_reader :full_name
|
13
|
+
|
14
|
+
##
|
15
|
+
# @!attribute [r] scope
|
16
|
+
# @return [:instance, :class]
|
17
|
+
#
|
18
|
+
attr_reader :scope
|
19
|
+
|
20
|
+
##
|
21
|
+
# @!attribute [r] body
|
22
|
+
# @return [Proc]
|
23
|
+
#
|
24
|
+
attr_reader :body
|
25
|
+
|
26
|
+
##
|
27
|
+
# @param full_name [String, Symbol]
|
28
|
+
# @param scope [:instance, :class]
|
29
|
+
# @param body [Proc]
|
30
|
+
# @return [void]
|
31
|
+
#
|
32
|
+
def initialize(full_name:, scope:, body:)
|
33
|
+
@full_name = full_name
|
34
|
+
@scope = scope
|
35
|
+
@body = body
|
36
|
+
end
|
37
|
+
|
38
|
+
##
|
39
|
+
# @return [String]
|
40
|
+
#
|
41
|
+
def name
|
42
|
+
@name ||= full_name_parts.last
|
43
|
+
end
|
44
|
+
|
45
|
+
##
|
46
|
+
# @return [Array<ConvenientService::Support::DependencyContainer::Entities::Namespace>]
|
47
|
+
#
|
48
|
+
def namespaces
|
49
|
+
@namespaces ||= full_name_parts.slice(0..-2).map { |part| Entities::Namespace.new(name: part) }
|
50
|
+
end
|
51
|
+
|
52
|
+
##
|
53
|
+
# @param mod [Module]
|
54
|
+
# @return [ConvenientService::Support::DependencyContainer::Entities::Method]
|
55
|
+
#
|
56
|
+
def define_in_module!(mod)
|
57
|
+
##
|
58
|
+
# NOTE: `innermost_namespace` is just `mod`, when `namespaces` are empty.
|
59
|
+
#
|
60
|
+
innermost_namespace =
|
61
|
+
namespaces.reduce(mod) do |namespace, sub_namespace|
|
62
|
+
already_defined_sub_namespace = namespace.namespaces.find_by(name: sub_namespace.name)
|
63
|
+
|
64
|
+
##
|
65
|
+
# NOTE:
|
66
|
+
# - Reuses already defined namespace from previous "imports".
|
67
|
+
# - In contrast, same methods are always redefined.
|
68
|
+
#
|
69
|
+
next already_defined_sub_namespace if already_defined_sub_namespace
|
70
|
+
|
71
|
+
namespace.namespaces << sub_namespace
|
72
|
+
|
73
|
+
namespace.define_method(sub_namespace.name) { sub_namespace.body.call }
|
74
|
+
|
75
|
+
sub_namespace
|
76
|
+
end
|
77
|
+
|
78
|
+
##
|
79
|
+
# NOTE:
|
80
|
+
# - Same methods are redefined.
|
81
|
+
# - In contrast, same namespaces are always reused.
|
82
|
+
#
|
83
|
+
innermost_namespace.define_method(method.name, &method.body)
|
84
|
+
|
85
|
+
method
|
86
|
+
end
|
87
|
+
|
88
|
+
##
|
89
|
+
# @param other [Object] Can be any type.
|
90
|
+
# @return [Boolean]
|
91
|
+
#
|
92
|
+
def ==(other)
|
93
|
+
return unless other.instance_of?(self.class)
|
94
|
+
|
95
|
+
return false if full_name != other.full_name
|
96
|
+
return false if scope != other.scope
|
97
|
+
return false if body != other.body
|
98
|
+
|
99
|
+
true
|
100
|
+
end
|
101
|
+
|
102
|
+
private
|
103
|
+
|
104
|
+
##
|
105
|
+
# @return [ConvenientService::Support::DependencyContainer::Entities::Method]
|
106
|
+
#
|
107
|
+
def method
|
108
|
+
self
|
109
|
+
end
|
110
|
+
|
111
|
+
##
|
112
|
+
# @return [Array<String>]
|
113
|
+
#
|
114
|
+
def full_name_parts
|
115
|
+
@full_name_parts ||= Utils::String.split(full_name, ".", "::").map(&:to_sym)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ConvenientService
|
4
|
+
module Support
|
5
|
+
module DependencyContainer
|
6
|
+
module Entities
|
7
|
+
class MethodCollection
|
8
|
+
##
|
9
|
+
# @param methods [Array<ConvenientService::Support::DependencyContainer::Entities::Method>]
|
10
|
+
# @return [void]
|
11
|
+
#
|
12
|
+
def initialize(methods: [])
|
13
|
+
@methods = methods
|
14
|
+
end
|
15
|
+
|
16
|
+
##
|
17
|
+
# @param name [String, Symbol]
|
18
|
+
# @param full_name [String, Symbol]
|
19
|
+
# @param scope [:instance, :class]
|
20
|
+
# @return [ConvenientService::Support::DependencyContainer::Entities::Method, nil]
|
21
|
+
#
|
22
|
+
def find_by(name: Support::NOT_PASSED, full_name: Support::NOT_PASSED, scope: Support::NOT_PASSED)
|
23
|
+
rules = []
|
24
|
+
|
25
|
+
rules << ->(method) { method.name.to_s == name.to_s } if name != Support::NOT_PASSED
|
26
|
+
rules << ->(method) { method.full_name.to_s == full_name.to_s } if full_name != Support::NOT_PASSED
|
27
|
+
rules << ->(method) { method.scope == scope } if scope != Support::NOT_PASSED
|
28
|
+
|
29
|
+
condition = Utils::Proc.conjunct(rules)
|
30
|
+
|
31
|
+
methods.find(&condition)
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
# @param method [ConvenientService::Support::DependencyContainer::Entities::Method]
|
36
|
+
# @return [ConvenientService::Support::DependencyContainer::Entities::MethodCollection]
|
37
|
+
#
|
38
|
+
def <<(method)
|
39
|
+
methods << method
|
40
|
+
|
41
|
+
self
|
42
|
+
end
|
43
|
+
|
44
|
+
##
|
45
|
+
# @return [Boolean]
|
46
|
+
#
|
47
|
+
def empty?
|
48
|
+
methods.empty?
|
49
|
+
end
|
50
|
+
|
51
|
+
##
|
52
|
+
# @param method [ConvenientService::Support::DependencyContainer::Entities::Method]
|
53
|
+
# @return [Boolean]
|
54
|
+
#
|
55
|
+
def include?(method)
|
56
|
+
methods.include?(method)
|
57
|
+
end
|
58
|
+
|
59
|
+
##
|
60
|
+
# @return [ConvenientService::Support::DependencyContainer::Entities::MethodCollection]
|
61
|
+
#
|
62
|
+
def clear
|
63
|
+
methods.clear
|
64
|
+
|
65
|
+
self
|
66
|
+
end
|
67
|
+
|
68
|
+
##
|
69
|
+
# @return [Array]
|
70
|
+
#
|
71
|
+
def to_a
|
72
|
+
methods.to_a
|
73
|
+
end
|
74
|
+
|
75
|
+
##
|
76
|
+
# @param other [Object] Can be any type.
|
77
|
+
# @return [Boolean]
|
78
|
+
#
|
79
|
+
def ==(other)
|
80
|
+
return unless other.instance_of?(self.class)
|
81
|
+
|
82
|
+
return false if methods != other.methods
|
83
|
+
|
84
|
+
true
|
85
|
+
end
|
86
|
+
|
87
|
+
protected
|
88
|
+
|
89
|
+
##
|
90
|
+
# @!attribute [r] methods
|
91
|
+
# @return [Array<ConvenientService::Support::DependencyContainer::Entities::Method>]
|
92
|
+
#
|
93
|
+
attr_reader :methods
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ConvenientService
|
4
|
+
module Support
|
5
|
+
module DependencyContainer
|
6
|
+
module Entities
|
7
|
+
class Namespace
|
8
|
+
##
|
9
|
+
# @!attribute [r] name
|
10
|
+
# @return [String, Symbol]
|
11
|
+
#
|
12
|
+
attr_reader :name
|
13
|
+
|
14
|
+
##
|
15
|
+
# @param name [String, Symbol]
|
16
|
+
# @return [void]
|
17
|
+
#
|
18
|
+
def initialize(name:)
|
19
|
+
@name = name
|
20
|
+
end
|
21
|
+
|
22
|
+
##
|
23
|
+
# @return [Proc]
|
24
|
+
#
|
25
|
+
def body
|
26
|
+
@body ||= -> { namespace }
|
27
|
+
end
|
28
|
+
|
29
|
+
##
|
30
|
+
# @return [ConvenientService::Support::DependencyContainer::Entities::NamespaceCollection]
|
31
|
+
#
|
32
|
+
def namespaces
|
33
|
+
@namespaces ||= Entities::NamespaceCollection.new
|
34
|
+
end
|
35
|
+
|
36
|
+
##
|
37
|
+
# @param name [String, Symbol]
|
38
|
+
# @param body [Proc]
|
39
|
+
# @return [Symbol]
|
40
|
+
#
|
41
|
+
def define_method(name, &body)
|
42
|
+
define_singleton_method(name, &body)
|
43
|
+
end
|
44
|
+
|
45
|
+
##
|
46
|
+
# @param other [Object] Can be any type.
|
47
|
+
# @return [Boolean]
|
48
|
+
#
|
49
|
+
def ==(other)
|
50
|
+
return unless other.instance_of?(self.class)
|
51
|
+
|
52
|
+
return false if name != other.name
|
53
|
+
|
54
|
+
true
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
##
|
60
|
+
# @return [ConvenientService::Support::DependencyContainer::Entities::Namespace]
|
61
|
+
#
|
62
|
+
def namespace
|
63
|
+
self
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ConvenientService
|
4
|
+
module Support
|
5
|
+
module DependencyContainer
|
6
|
+
module Entities
|
7
|
+
class NamespaceCollection
|
8
|
+
##
|
9
|
+
# @param namespaces [Array<ConvenientService::Support::DependencyContainer::Entities::Namespace>]
|
10
|
+
# @return [void]
|
11
|
+
#
|
12
|
+
def initialize(namespaces: [])
|
13
|
+
@namespaces = namespaces
|
14
|
+
end
|
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
|
+
##
|
26
|
+
# @param name [String, Symbol]
|
27
|
+
# @return [ConvenientService::Support::DependencyContainer::Entities::Namespace, nil]
|
28
|
+
#
|
29
|
+
def find_by(name: Support::NOT_PASSED)
|
30
|
+
rules = []
|
31
|
+
|
32
|
+
rules << ->(namespace) { namespace.name.to_s == name.to_s } if name != Support::NOT_PASSED
|
33
|
+
|
34
|
+
condition = Utils::Proc.conjunct(rules)
|
35
|
+
|
36
|
+
namespaces.find(&condition)
|
37
|
+
end
|
38
|
+
|
39
|
+
##
|
40
|
+
# @param namespace [ConvenientService::Support::DependencyContainer::Entities::Namespace]
|
41
|
+
# @return [ConvenientService::Support::DependencyContainer::Entities::NamespaceCollection]
|
42
|
+
#
|
43
|
+
def <<(namespace)
|
44
|
+
namespaces << namespace
|
45
|
+
|
46
|
+
self
|
47
|
+
end
|
48
|
+
|
49
|
+
##
|
50
|
+
# @return [Boolean]
|
51
|
+
#
|
52
|
+
def empty?
|
53
|
+
namespaces.empty?
|
54
|
+
end
|
55
|
+
|
56
|
+
##
|
57
|
+
# @param namespace [ConvenientService::Support::DependencyContainer::Entities::Namespace]
|
58
|
+
# @return [Boolean]
|
59
|
+
#
|
60
|
+
def include?(namespace)
|
61
|
+
namespaces.include?(namespace)
|
62
|
+
end
|
63
|
+
|
64
|
+
##
|
65
|
+
# @return [ConvenientService::Support::DependencyContainer::Entities::NamespaceCollection]
|
66
|
+
#
|
67
|
+
def clear
|
68
|
+
namespaces.clear
|
69
|
+
|
70
|
+
self
|
71
|
+
end
|
72
|
+
|
73
|
+
##
|
74
|
+
# @return [Array]
|
75
|
+
#
|
76
|
+
def to_a
|
77
|
+
namespaces.to_a
|
78
|
+
end
|
79
|
+
|
80
|
+
##
|
81
|
+
# @param other [Object] Can be any type.
|
82
|
+
# @return [Boolean]
|
83
|
+
#
|
84
|
+
def ==(other)
|
85
|
+
return unless other.instance_of?(self.class)
|
86
|
+
|
87
|
+
return false if namespaces != other.namespaces
|
88
|
+
|
89
|
+
true
|
90
|
+
end
|
91
|
+
|
92
|
+
protected
|
93
|
+
|
94
|
+
##
|
95
|
+
# @!attribute [r] namespaces
|
96
|
+
# @return [Array<ConvenientService::Support::DependencyContainer::Entities::Namespace>]
|
97
|
+
#
|
98
|
+
attr_reader :namespaces
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ConvenientService
|
4
|
+
module Support
|
5
|
+
module DependencyContainer
|
6
|
+
module Errors
|
7
|
+
class NotExportableModule < ConvenientService::Error
|
8
|
+
##
|
9
|
+
# @param mod [Module]
|
10
|
+
# @return [void]
|
11
|
+
#
|
12
|
+
def initialize(mod:)
|
13
|
+
message = <<~TEXT
|
14
|
+
Module `#{mod}` can NOT export methods.
|
15
|
+
|
16
|
+
Did you forget to include `ConvenientService::Container.export` into it?
|
17
|
+
TEXT
|
18
|
+
|
19
|
+
super(message)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class NotExportedMethod < ConvenientService::Error
|
24
|
+
##
|
25
|
+
# @param method_name [String]
|
26
|
+
# @param method_scope [Symbol]
|
27
|
+
# @param mod [Module]
|
28
|
+
# @return [void]
|
29
|
+
#
|
30
|
+
def initialize(method_name:, method_scope:, mod:)
|
31
|
+
message = <<~TEXT
|
32
|
+
Module `#{mod}` does NOT export method `#{method_name}` with `#{method_scope}` scope.
|
33
|
+
|
34
|
+
Did you forget to export if from `#{mod}`? For example:
|
35
|
+
|
36
|
+
module #{mod}
|
37
|
+
export #{method_name}, scope: :#{method_scope} do |*args, **kwargs, &block|
|
38
|
+
# ...
|
39
|
+
end
|
40
|
+
end
|
41
|
+
TEXT
|
42
|
+
|
43
|
+
super(message)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ConvenientService
|
4
|
+
module Support
|
5
|
+
module DependencyContainer
|
6
|
+
module Export
|
7
|
+
include Support::Concern
|
8
|
+
|
9
|
+
class_methods do
|
10
|
+
##
|
11
|
+
# @param full_name [String, Symbol]
|
12
|
+
# @param scope [:instance, :class]
|
13
|
+
# @param body [Proc]
|
14
|
+
# @return [ConvenientService::Support::DependencyContainer::Entities::Method]
|
15
|
+
#
|
16
|
+
def export(full_name, scope: Constants::DEFAULT_SCOPE, &body)
|
17
|
+
Entities::Method.new(full_name: full_name, scope: scope, body: body).tap { |method| exported_methods << method }
|
18
|
+
end
|
19
|
+
|
20
|
+
##
|
21
|
+
# @return [ConvenientService::Support::DependencyContainer::Entities::MethodCollection]
|
22
|
+
#
|
23
|
+
def exported_methods
|
24
|
+
@exported_methods ||= Entities::MethodCollection.new
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ConvenientService
|
4
|
+
module Support
|
5
|
+
module DependencyContainer
|
6
|
+
module Import
|
7
|
+
include Support::Concern
|
8
|
+
|
9
|
+
class_methods do
|
10
|
+
##
|
11
|
+
# @param full_name [String, Symbol]
|
12
|
+
# @param from [Module]
|
13
|
+
# @param scope [:instance, :class]
|
14
|
+
# @param prepend [Boolean]
|
15
|
+
# @return [ConvenientService::Support::DependencyContainer::Entities::Method]
|
16
|
+
#
|
17
|
+
def import(full_name, from:, scope: Constants::DEFAULT_SCOPE, prepend: Constants::DEFAULT_PREPEND)
|
18
|
+
raise Errors::NotExportableModule.new(mod: from) unless Utils::Module.include_module?(from, DependencyContainer::Export)
|
19
|
+
|
20
|
+
method = from.exported_methods.find_by(full_name: full_name, scope: scope)
|
21
|
+
|
22
|
+
raise Errors::NotExportedMethod.new(method_name: full_name, method_scope: scope, mod: from) unless method
|
23
|
+
|
24
|
+
Commands::ImportMethod.call(importing_module: self, exporting_module: from, method: method, scope: scope, prepend: prepend)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "dependency_container/commands"
|
4
|
+
require_relative "dependency_container/constants"
|
5
|
+
require_relative "dependency_container/entities"
|
6
|
+
require_relative "dependency_container/errors"
|
7
|
+
|
8
|
+
require_relative "dependency_container/export"
|
9
|
+
require_relative "dependency_container/import"
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "support/not_passed"
|
3
4
|
require_relative "support/concern"
|
4
5
|
|
5
6
|
require_relative "support/abstract_method"
|
@@ -8,6 +9,7 @@ require_relative "support/castable"
|
|
8
9
|
require_relative "support/command"
|
9
10
|
require_relative "support/copyable"
|
10
11
|
require_relative "support/delegate"
|
12
|
+
require_relative "support/dependency_container"
|
11
13
|
require_relative "support/finite_loop"
|
12
14
|
require_relative "support/gems"
|
13
15
|
require_relative "support/middleware"
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
##
|
4
|
+
# @example Two args form (works as GetOwnConst).
|
5
|
+
# module Test
|
6
|
+
# end
|
7
|
+
#
|
8
|
+
# ConvenientService::Utils::Module::FetchOwnConst.call(Test, :File)
|
9
|
+
# # => nil, not File from Ruby Core.
|
10
|
+
#
|
11
|
+
# module Test
|
12
|
+
# class File
|
13
|
+
# end
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# ConvenientService::Utils::Module::FetchOwnConst.call(Test, :File)
|
17
|
+
# # => Test::File
|
18
|
+
#
|
19
|
+
# @example Two args + block form.
|
20
|
+
# module Test
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# ConvenientService::Utils::Module::FetchOwnConst.call(Test, :File) { Class.new }
|
24
|
+
# # => Test::File, just created.
|
25
|
+
#
|
26
|
+
# module Test
|
27
|
+
# class File
|
28
|
+
# end
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# ConvenientService::Utils::Module::FetchOwnConst.call(Test, :File)
|
32
|
+
# # => Test::File, already existing.
|
33
|
+
#
|
34
|
+
module ConvenientService
|
35
|
+
module Utils
|
36
|
+
module Module
|
37
|
+
class FetchOwnConst < Support::Command
|
38
|
+
##
|
39
|
+
# @!attribute [r] mod
|
40
|
+
# @return [Class, Module]
|
41
|
+
#
|
42
|
+
attr_reader :mod
|
43
|
+
|
44
|
+
##
|
45
|
+
# @!attribute [r] const_name
|
46
|
+
# @return [Symbol]
|
47
|
+
#
|
48
|
+
attr_reader :const_name
|
49
|
+
|
50
|
+
##
|
51
|
+
# @!attribute [r] fallback_block
|
52
|
+
# @return [Proc, nil]
|
53
|
+
#
|
54
|
+
attr_reader :fallback_block
|
55
|
+
|
56
|
+
##
|
57
|
+
# @param mod [Class, Module]
|
58
|
+
# @param const_name [Symbol]
|
59
|
+
# @param fallback_block [Proc]
|
60
|
+
# @return [void]
|
61
|
+
#
|
62
|
+
def initialize(mod, const_name, &fallback_block)
|
63
|
+
@mod = mod
|
64
|
+
@const_name = const_name
|
65
|
+
@fallback_block = fallback_block
|
66
|
+
end
|
67
|
+
|
68
|
+
##
|
69
|
+
# @return [Object] Value of own const. Can be any type.
|
70
|
+
#
|
71
|
+
# @internal
|
72
|
+
# TODO: Wrap by mutex?
|
73
|
+
#
|
74
|
+
def call
|
75
|
+
##
|
76
|
+
# NOTE: > If `inherit` is `false`, the lookup only checks the constants in the receiver:
|
77
|
+
# https://ruby-doc.org/core-3.0.0/Module.html#method-i-const_defined-3F
|
78
|
+
#
|
79
|
+
return mod.const_get(const_name, false) if mod.const_defined?(const_name, false)
|
80
|
+
|
81
|
+
return mod.const_set(const_name, fallback_block.call) if fallback_block
|
82
|
+
|
83
|
+
nil
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ConvenientService
|
4
|
+
module Utils
|
5
|
+
module Module
|
6
|
+
class IncludeModule < Support::Command
|
7
|
+
##
|
8
|
+
# @!attribute [r] mod
|
9
|
+
# @return [Module]
|
10
|
+
#
|
11
|
+
attr_reader :mod
|
12
|
+
|
13
|
+
##
|
14
|
+
# @!attribute [r] other_mod
|
15
|
+
# @return [Module]
|
16
|
+
#
|
17
|
+
attr_reader :other_mod
|
18
|
+
|
19
|
+
##
|
20
|
+
# @param mod [Module]
|
21
|
+
# @param other_mod [Module]
|
22
|
+
# @return [void]
|
23
|
+
#
|
24
|
+
def initialize(mod, other_mod)
|
25
|
+
@mod = mod
|
26
|
+
@other_mod = other_mod
|
27
|
+
end
|
28
|
+
|
29
|
+
##
|
30
|
+
# @return [Boolean]
|
31
|
+
#
|
32
|
+
def call
|
33
|
+
mod.included_modules.include?(other_mod)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -1,9 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative "module/class_method_defined"
|
4
|
+
require_relative "module/fetch_own_const"
|
4
5
|
require_relative "module/get_own_instance_method"
|
5
6
|
require_relative "module/get_own_const"
|
6
7
|
require_relative "module/has_own_instance_method"
|
8
|
+
require_relative "module/include_module"
|
7
9
|
require_relative "module/instance_method_defined"
|
8
10
|
|
9
11
|
module ConvenientService
|
@@ -19,6 +21,10 @@ module ConvenientService
|
|
19
21
|
ClassMethodDefined.call(...)
|
20
22
|
end
|
21
23
|
|
24
|
+
def fetch_own_const(...)
|
25
|
+
FetchOwnConst.call(...)
|
26
|
+
end
|
27
|
+
|
22
28
|
def get_own_instance_method(...)
|
23
29
|
GetOwnInstanceMethod.call(...)
|
24
30
|
end
|
@@ -31,6 +37,10 @@ module ConvenientService
|
|
31
37
|
HasOwnInstanceMethod.call(...)
|
32
38
|
end
|
33
39
|
|
40
|
+
def include_module?(...)
|
41
|
+
IncludeModule.call(...)
|
42
|
+
end
|
43
|
+
|
34
44
|
def instance_method_defined?(...)
|
35
45
|
InstanceMethodDefined.call(...)
|
36
46
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ConvenientService
|
4
|
+
module Utils
|
5
|
+
module String
|
6
|
+
class Split < Support::Command
|
7
|
+
##
|
8
|
+
# @!attribute [r] string
|
9
|
+
# @return [#to_s]
|
10
|
+
#
|
11
|
+
attr_reader :string
|
12
|
+
|
13
|
+
##
|
14
|
+
# @!attribute [r] delimiters
|
15
|
+
# @return [Array<String>]
|
16
|
+
#
|
17
|
+
attr_reader :delimiters
|
18
|
+
|
19
|
+
##
|
20
|
+
# @param string [Symbol, String]
|
21
|
+
# @param delimiters [Array<String>]
|
22
|
+
# @return [void]
|
23
|
+
#
|
24
|
+
def initialize(string, *delimiters)
|
25
|
+
@string = string
|
26
|
+
@delimiters = delimiters
|
27
|
+
end
|
28
|
+
|
29
|
+
##
|
30
|
+
# @return [String]
|
31
|
+
#
|
32
|
+
# @internal
|
33
|
+
# https://stackoverflow.com/a/51380514/12201472
|
34
|
+
#
|
35
|
+
def call
|
36
|
+
string.to_s.split(::Regexp.union(delimiters))
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative "string/camelize"
|
4
|
+
require_relative "string/split"
|
4
5
|
|
5
6
|
module ConvenientService
|
6
7
|
module Utils
|
@@ -9,6 +10,10 @@ module ConvenientService
|
|
9
10
|
def camelize(...)
|
10
11
|
Camelize.call(...)
|
11
12
|
end
|
13
|
+
|
14
|
+
def split(...)
|
15
|
+
Split.call(...)
|
16
|
+
end
|
12
17
|
end
|
13
18
|
end
|
14
19
|
end
|
data/lib/convenient_service.rb
CHANGED
@@ -29,3 +29,9 @@ require_relative "convenient_service/core"
|
|
29
29
|
require_relative "convenient_service/common"
|
30
30
|
require_relative "convenient_service/service"
|
31
31
|
require_relative "convenient_service/configs"
|
32
|
+
|
33
|
+
##
|
34
|
+
# @internal
|
35
|
+
# Convenient Service Aliases.
|
36
|
+
#
|
37
|
+
require_relative "convenient_service/aliases"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: convenient_service
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marian Kostyk
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-01-
|
11
|
+
date: 2023-01-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: appraisal
|
@@ -182,16 +182,16 @@ dependencies:
|
|
182
182
|
name: rubocop
|
183
183
|
requirement: !ruby/object:Gem::Requirement
|
184
184
|
requirements:
|
185
|
-
- - "
|
185
|
+
- - "~>"
|
186
186
|
- !ruby/object:Gem::Version
|
187
|
-
version:
|
187
|
+
version: 1.40.0
|
188
188
|
type: :development
|
189
189
|
prerelease: false
|
190
190
|
version_requirements: !ruby/object:Gem::Requirement
|
191
191
|
requirements:
|
192
|
-
- - "
|
192
|
+
- - "~>"
|
193
193
|
- !ruby/object:Gem::Version
|
194
|
-
version:
|
194
|
+
version: 1.40.0
|
195
195
|
- !ruby/object:Gem::Dependency
|
196
196
|
name: rubocop-rspec
|
197
197
|
requirement: !ruby/object:Gem::Requirement
|
@@ -331,6 +331,7 @@ files:
|
|
331
331
|
- docker/3.1/Dockerfile
|
332
332
|
- env.rb
|
333
333
|
- lib/convenient_service.rb
|
334
|
+
- lib/convenient_service/aliases.rb
|
334
335
|
- lib/convenient_service/common.rb
|
335
336
|
- lib/convenient_service/common/plugins.rb
|
336
337
|
- lib/convenient_service/common/plugins/aliases.rb
|
@@ -702,12 +703,26 @@ files:
|
|
702
703
|
- lib/convenient_service/support/concern.rb
|
703
704
|
- lib/convenient_service/support/copyable.rb
|
704
705
|
- lib/convenient_service/support/delegate.rb
|
706
|
+
- lib/convenient_service/support/dependency_container.rb
|
707
|
+
- lib/convenient_service/support/dependency_container/commands.rb
|
708
|
+
- lib/convenient_service/support/dependency_container/commands/create_methods_module.rb
|
709
|
+
- lib/convenient_service/support/dependency_container/commands/import_method.rb
|
710
|
+
- lib/convenient_service/support/dependency_container/constants.rb
|
711
|
+
- lib/convenient_service/support/dependency_container/entities.rb
|
712
|
+
- lib/convenient_service/support/dependency_container/entities/method.rb
|
713
|
+
- lib/convenient_service/support/dependency_container/entities/method_collection.rb
|
714
|
+
- lib/convenient_service/support/dependency_container/entities/namespace.rb
|
715
|
+
- lib/convenient_service/support/dependency_container/entities/namespace_collection.rb
|
716
|
+
- lib/convenient_service/support/dependency_container/errors.rb
|
717
|
+
- lib/convenient_service/support/dependency_container/export.rb
|
718
|
+
- lib/convenient_service/support/dependency_container/import.rb
|
705
719
|
- lib/convenient_service/support/finite_loop.rb
|
706
720
|
- lib/convenient_service/support/gems.rb
|
707
721
|
- lib/convenient_service/support/gems/active_model.rb
|
708
722
|
- lib/convenient_service/support/gems/rspec.rb
|
709
723
|
- lib/convenient_service/support/middleware.rb
|
710
724
|
- lib/convenient_service/support/middleware/stack_builder.rb
|
725
|
+
- lib/convenient_service/support/not_passed.rb
|
711
726
|
- lib/convenient_service/support/raw_value.rb
|
712
727
|
- lib/convenient_service/support/ruby.rb
|
713
728
|
- lib/convenient_service/support/version.rb
|
@@ -731,9 +746,11 @@ files:
|
|
731
746
|
- lib/convenient_service/utils/method/defined.rb
|
732
747
|
- lib/convenient_service/utils/module.rb
|
733
748
|
- lib/convenient_service/utils/module/class_method_defined.rb
|
749
|
+
- lib/convenient_service/utils/module/fetch_own_const.rb
|
734
750
|
- lib/convenient_service/utils/module/get_own_const.rb
|
735
751
|
- lib/convenient_service/utils/module/get_own_instance_method.rb
|
736
752
|
- lib/convenient_service/utils/module/has_own_instance_method.rb
|
753
|
+
- lib/convenient_service/utils/module/include_module.rb
|
737
754
|
- lib/convenient_service/utils/module/instance_method_defined.rb
|
738
755
|
- lib/convenient_service/utils/object.rb
|
739
756
|
- lib/convenient_service/utils/object/instance_variable_fetch.rb
|
@@ -743,6 +760,7 @@ files:
|
|
743
760
|
- lib/convenient_service/utils/proc/exec_config.rb
|
744
761
|
- lib/convenient_service/utils/string.rb
|
745
762
|
- lib/convenient_service/utils/string/camelize.rb
|
763
|
+
- lib/convenient_service/utils/string/split.rb
|
746
764
|
- lib/convenient_service/version.rb
|
747
765
|
- logo.png
|
748
766
|
homepage: https://github.com/marian13/convenient_service
|