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.
Files changed (28) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +7 -0
  3. data/convenient_service.gemspec +1 -1
  4. data/lib/convenient_service/aliases.rb +5 -0
  5. data/lib/convenient_service/support/dependency_container/commands/create_methods_module.rb +27 -0
  6. data/lib/convenient_service/support/dependency_container/commands/import_method.rb +111 -0
  7. data/lib/convenient_service/support/dependency_container/commands.rb +4 -0
  8. data/lib/convenient_service/support/dependency_container/constants.rb +15 -0
  9. data/lib/convenient_service/support/dependency_container/entities/method.rb +121 -0
  10. data/lib/convenient_service/support/dependency_container/entities/method_collection.rb +98 -0
  11. data/lib/convenient_service/support/dependency_container/entities/namespace.rb +69 -0
  12. data/lib/convenient_service/support/dependency_container/entities/namespace_collection.rb +103 -0
  13. data/lib/convenient_service/support/dependency_container/entities.rb +6 -0
  14. data/lib/convenient_service/support/dependency_container/errors.rb +49 -0
  15. data/lib/convenient_service/support/dependency_container/export.rb +30 -0
  16. data/lib/convenient_service/support/dependency_container/import.rb +30 -0
  17. data/lib/convenient_service/support/dependency_container.rb +9 -0
  18. data/lib/convenient_service/support/not_passed.rb +7 -0
  19. data/lib/convenient_service/support.rb +2 -0
  20. data/lib/convenient_service/utils/module/fetch_own_const.rb +88 -0
  21. data/lib/convenient_service/utils/module/include_module.rb +38 -0
  22. data/lib/convenient_service/utils/module.rb +10 -0
  23. data/lib/convenient_service/utils/proc/conjunct.rb +1 -1
  24. data/lib/convenient_service/utils/string/split.rb +41 -0
  25. data/lib/convenient_service/utils/string.rb +5 -0
  26. data/lib/convenient_service/version.rb +1 -1
  27. data/lib/convenient_service.rb +6 -0
  28. metadata +24 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 481cc240efe2b9443d13ea66fc70dc2cd1b477c291be24b1b9e66af9e9e26e65
4
- data.tar.gz: 07caed3e04809cd78e96818e69c99f9337a9882f689c05709ff57d38e6c5940f
3
+ metadata.gz: 7655bb52a95f02a3f973c4f26e8e881ebf2dec66e056de3e085515b8e1c9b8f9
4
+ data.tar.gz: 440d3e574c167e88ca942e98eb022665faf918933d20789d4acc50f90bd0e9e8
5
5
  SHA512:
6
- metadata.gz: 35b346de371b82d3d8775a68783e1fdce3c42709bfb7aaa5a864f5bbb9c4ba494eb2f6a7f7ead303f5dcde1a079256c1cc881006cff5bc600b3c0e48a6810f6e
7
- data.tar.gz: dac03d20c0c10765f4c1e5530d0f9d92a1ee0723f98a94f0a0804d13e2f7e3c8d28d2052a0037c08d6f5b49726038d55069a89bf3143d01b298a58e4a223c32b
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
 
@@ -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,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ConvenientService
4
+ DependencyContainer = ::ConvenientService::Support::DependencyContainer
5
+ end
@@ -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,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "commands/create_methods_module"
4
+ require_relative "commands/import_method"
@@ -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,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "entities/method_collection"
4
+ require_relative "entities/method"
5
+ require_relative "entities/namespace_collection"
6
+ require_relative "entities/namespace"
@@ -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"
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ConvenientService
4
+ module Support
5
+ NOT_PASSED = ::Object.new
6
+ end
7
+ end
@@ -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
@@ -29,7 +29,7 @@ module ConvenientService
29
29
  # - https://en.wikipedia.org/wiki/Logical_conjunction
30
30
  #
31
31
  def call
32
- return ->(item) { true } if procs.none?
32
+ return ->(item) {} if procs.none?
33
33
 
34
34
  return procs.first if procs.one?
35
35
 
@@ -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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ConvenientService
4
- VERSION = "0.4.0"
4
+ VERSION = "0.5.0"
5
5
  end
@@ -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.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-03 00:00:00.000000000 Z
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: '0'
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: '0'
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