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.
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