convenient_service 0.4.0 → 0.5.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/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
|