eco-helpers 3.0.27 → 3.0.28
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 +39 -1
- data/eco-helpers.gemspec +1 -0
- data/lib/eco/api/common/class_helpers.rb +1 -136
- data/lib/eco/api/common/loaders/config/cli.rb +1 -1
- data/lib/eco/api/common/loaders/config/session.rb +1 -1
- data/lib/eco/api/common/loaders/config/workflow.rb +1 -1
- data/lib/eco/api/common/loaders/config.rb +2 -5
- data/lib/eco/api/common/loaders/use_case/target_model.rb +1 -1
- data/lib/eco/api/common/loaders/use_case/type.rb +1 -1
- data/lib/eco/api/common/people/supervisor_helpers.rb +3 -1
- data/lib/eco/api/common/session/logger/channels.rb +1 -0
- data/lib/eco/api/common/session/sftp.rb +9 -2
- data/lib/eco/api/session/batch/job/sets.rb +1 -0
- data/lib/eco/api/session/batch/job/type.rb +1 -0
- data/lib/eco/api/session/batch/launcher/valid_methods.rb +3 -2
- data/lib/eco/api/usecases/base_case/model.rb +2 -1
- data/lib/eco/api/usecases/base_case/type.rb +2 -1
- data/lib/eco/api/usecases/base_io/validations.rb +2 -1
- data/lib/eco/api/usecases/graphql/helpers/location/command/diffs/stages/commandable.rb +3 -2
- data/lib/eco/api/usecases/lib/files/file_pattern.rb +0 -2
- data/lib/eco/api/usecases/lib/files/sftp.rb +7 -4
- data/lib/eco/api/usecases/samples/drivers/sftp_sample.rb +3 -1
- data/lib/eco/data/files/helpers.rb +4 -2
- data/lib/eco/data/fuzzy_match.rb +4 -2
- data/lib/eco/data/hashes/diff_result/meta.rb +2 -1
- data/lib/eco/data/locations/node_diff/accessors.rb +2 -1
- data/lib/eco/language/delegation/chainable_delegator.rb +18 -0
- data/lib/eco/language/delegation/delegating_missing.rb +104 -0
- data/lib/eco/language/delegation/delegating_missing_const.rb +53 -0
- data/lib/eco/language/delegation/delegating_missing_on_class.rb +53 -0
- data/lib/eco/language/delegation/{const_delegator.rb → for_delegator/const_delegator.rb} +8 -6
- data/lib/eco/language/delegation/{const_lookup_hooks.rb → for_delegator/const_lookup_hooks.rb} +34 -16
- data/lib/eco/language/delegation/{delegated_class.rb → for_delegator/delegated_class.rb} +6 -19
- data/lib/eco/language/delegation/for_delegator.rb +11 -0
- data/lib/eco/language/delegation.rb +5 -3
- data/lib/eco/language/klass/builder.rb +29 -0
- data/lib/eco/language/klass/helpers_built.rb +9 -0
- data/lib/eco/language/klass/hierarchy.rb +34 -0
- data/lib/eco/language/klass/inheritable_class_vars.rb +45 -0
- data/lib/eco/language/klass/naming.rb +21 -0
- data/lib/eco/language/klass/resolver.rb +30 -0
- data/lib/eco/language/klass/when_inherited.rb +10 -13
- data/lib/eco/language/klass.rb +6 -0
- data/lib/eco/language/methods.rb +0 -1
- data/lib/eco/language/strings/underscore.rb +17 -0
- data/lib/eco/language/strings.rb +8 -0
- data/lib/eco/language.rb +1 -0
- data/lib/eco/version.rb +1 -1
- metadata +32 -6
- data/lib/eco/language/methods/delegate_missing.rb +0 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3f36ef48b8d70b2ac8b50e32a823d99d8bec5e32a76975357cf2298a6247a694
|
4
|
+
data.tar.gz: 60c6b240668df642d9bba41bc67011a02f7602e143aaabc2e4a25d2f9aa5d5dc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 70393a40919bf80751385734885c88914a80acc47a80d5a068be431b4abd2e9677d8e1707dbeaf8510de49dc519d00441df3ffe2bed4ee8f50663895caf2e778
|
7
|
+
data.tar.gz: 44cc94d912bdcee5ec8140ce8d78a0b2a10feb8c609944147446e4337641ca53394ee3e798b17d970cae887b07313ed511a4840e47af7fa903595311a5923eba
|
data/CHANGELOG.md
CHANGED
@@ -2,7 +2,45 @@
|
|
2
2
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
4
4
|
|
5
|
-
## [3.0.
|
5
|
+
## [3.0.29] - 2025-03-xx
|
6
|
+
|
7
|
+
### Added
|
8
|
+
|
9
|
+
### Changed
|
10
|
+
|
11
|
+
### Fixed
|
12
|
+
|
13
|
+
## [3.0.28] - 2025-03-31
|
14
|
+
|
15
|
+
### Added
|
16
|
+
|
17
|
+
- `Language::Delegation::DelegatingMissing` (rails alike, but ending with `ing`).
|
18
|
+
- `Language::Delegation::DelegatingMissingConst`.
|
19
|
+
- `Language::Delegation::ChainableDelegator`
|
20
|
+
- `Language::Strings::Underscore`
|
21
|
+
- `Eco::API::UseCases::Lib::Files::Sftp`
|
22
|
+
- **Added** named argument `only_latest` to fetch only latest file (**newest**).
|
23
|
+
|
24
|
+
### Changed
|
25
|
+
|
26
|
+
- `Eco::API::UseCases::Lib::Files::Sftp#local_folder`
|
27
|
+
- **Remove** default to `.` (current/root directory).
|
28
|
+
- **Moved** `Language::Methods::DelegateMissing` to `Language::Delegation::DelegatingMissingOnClass`
|
29
|
+
- **Renamed** `::delegate_missing_to` to `::delegating_missing_on_class_to`
|
30
|
+
- **Moved** `DelegatedClass`, `ConstDelegator` and `ConstLookupHooks` from `Language::Delegation` to `Language::Delegation::ForDelegator`
|
31
|
+
- `DelegatedClass`
|
32
|
+
- **Moved** `#initialize` to the **new** `ChainableDelegator` sample
|
33
|
+
- **Moved** requirement for base to be a `Delegator` or subclass thereof.
|
34
|
+
- The requirement is now part of `ConstLookupHooks`, as this particular concern only makes sense on `Delegator` subclasses.
|
35
|
+
- **Moved** (by keeping backwards compatibility) `Eco::API::Common::ClassHelpers` to decoupled helpers in `Eco::Language::Klass`
|
36
|
+
- **Manage Exception** on `Eco::API::Common::Session::SFTP#upload`
|
37
|
+
- **Added** remote `dest_file` feedback
|
38
|
+
|
39
|
+
### Fixed
|
40
|
+
|
41
|
+
- **Remove** recursive call on `Lib::Files::FilePattern#file_pattern_const`
|
42
|
+
|
43
|
+
## [3.0.27] - 2025-03-29
|
6
44
|
|
7
45
|
### Added
|
8
46
|
|
data/eco-helpers.gemspec
CHANGED
@@ -27,6 +27,7 @@ Gem::Specification.new do |spec|
|
|
27
27
|
#spec.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
28
28
|
spec.require_paths = ['lib']
|
29
29
|
|
30
|
+
spec.add_development_dependency 'byebug'
|
30
31
|
spec.add_development_dependency 'rake', '>= 13.0.3', '< 14'
|
31
32
|
spec.add_development_dependency 'redcarpet', '>= 3.6.0', '< 4'
|
32
33
|
spec.add_development_dependency 'rspec', '>= 3.12.0', '< 4'
|
@@ -2,142 +2,7 @@ module Eco
|
|
2
2
|
module API
|
3
3
|
module Common
|
4
4
|
module ClassHelpers
|
5
|
-
|
6
|
-
def class_resolver(name, klass)
|
7
|
-
define_singleton_method(name) { resolve_class(klass) }
|
8
|
-
define_method(name) { self.class.resolve_class(klass) }
|
9
|
-
end
|
10
|
-
|
11
|
-
# With given a `klass` name it resolves to an actual `Class`
|
12
|
-
# @return [Class] the class that was being searched by name `klass`.
|
13
|
-
def resolve_class(klass, exception: true)
|
14
|
-
@resolved ||= {}
|
15
|
-
@resolved[klass] ||=
|
16
|
-
case klass
|
17
|
-
when Class
|
18
|
-
klass
|
19
|
-
when String
|
20
|
-
begin
|
21
|
-
Kernel.const_get(klass)
|
22
|
-
rescue NameError
|
23
|
-
raise if exception
|
24
|
-
end
|
25
|
-
when Symbol
|
26
|
-
resolve_class(send(klass))
|
27
|
-
else
|
28
|
-
raise "Unknown class: #{klass}" if exception
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
# Helper to normalize `key` into a correct `ruby` **constant name**
|
33
|
-
# @param key [String, Symbol] to be normalized
|
34
|
-
# @return [String] a correct constant name
|
35
|
-
def to_constant(key)
|
36
|
-
key.to_s.strip.split(/[\-\_ ]/i).compact.map do |str|
|
37
|
-
str.slice(0).upcase + str.slice(1..-1).downcase
|
38
|
-
end.join
|
39
|
-
end
|
40
|
-
|
41
|
-
# Helper to create an instance variable `name`
|
42
|
-
# @param [String, Symbol] the name of the variable
|
43
|
-
# @reutrn [String] the name of the created instance variable
|
44
|
-
def instance_variable_name(name)
|
45
|
-
str = name.to_s
|
46
|
-
str = "@#{str}" unless str.start_with?("@")
|
47
|
-
str
|
48
|
-
end
|
49
|
-
|
50
|
-
# If the class for `name` exists, it returns it. Otherwise it generates it.
|
51
|
-
# @param name [String, Symbol] the name of the new class
|
52
|
-
# @param inherits [Class] the parent class to _inherit_ from
|
53
|
-
# @param parent_space [String] parent namespace of the generated class, if not given: `self`
|
54
|
-
# @yield [child_class] configure the new class
|
55
|
-
# @yieldparam child_class [Class] the new class
|
56
|
-
# @return [Class] the new generated class
|
57
|
-
def new_class(name, inherits:, parent_space: nil)
|
58
|
-
name = name.to_sym.freeze
|
59
|
-
class_name = to_constant(name)
|
60
|
-
parent_space = parent_space ? resolve_class(parent_space) : self
|
61
|
-
full_class_name = "#{parent_space}::#{class_name}"
|
62
|
-
|
63
|
-
unless (target_class = resolve_class(full_class_name, exception: false))
|
64
|
-
target_class = Class.new(inherits)
|
65
|
-
parent_space.const_set class_name, target_class
|
66
|
-
end
|
67
|
-
|
68
|
-
target_class.tap do |klass|
|
69
|
-
yield(klass) if block_given?
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
# Finds all child classes of the current class.
|
74
|
-
# @param parent_class [Class] the parent class we want to find children of.
|
75
|
-
# @param direct [Boolean] it will only include direct child classes.
|
76
|
-
# @param scope [nil, Array] to only look for descendants among the ones in `scope`.
|
77
|
-
# @return [Arrary<Class>] the child classes in hierarchy order.
|
78
|
-
def descendants(parent_class: self, direct: false, scope: nil)
|
79
|
-
scope ||= ObjectSpace.each_object(::Class)
|
80
|
-
return [] if scope.empty?
|
81
|
-
scope.select do |klass|
|
82
|
-
klass < parent_class
|
83
|
-
end.sort do |k_1, k_2|
|
84
|
-
next -1 if k_2 < k_1
|
85
|
-
next 1 if k_1 < k_2
|
86
|
-
0
|
87
|
-
end.tap do |siblings|
|
88
|
-
if direct
|
89
|
-
siblings.reject! do |si|
|
90
|
-
siblings.any? {|s| si < s}
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
# @param parent_class [Class] the parent class we want to find children of.
|
97
|
-
# @param direct [Boolean] it will only include direct child classes.
|
98
|
-
# @return [Boolean] `true` if the current class has child classes, and `false` otherwise.
|
99
|
-
def descendants?(parent_class: self, direct: false)
|
100
|
-
descendants(parent_class: parent_class, direct: direct).length.positive?
|
101
|
-
end
|
102
|
-
|
103
|
-
# Keeps track on class instance variables that should be inherited by child classes.
|
104
|
-
# @note
|
105
|
-
# - subclasses will inherit the value as is at that moment
|
106
|
-
# - any change afterwards will be only on the specific class (in line with class instance variables)
|
107
|
-
# - adapted from https://stackoverflow.com/a/10729812/4352306
|
108
|
-
# TODO: this separates the logic of the method to the instance var.
|
109
|
-
# Think if would be possible to join them somehow.
|
110
|
-
def inheritable_class_vars(*vars)
|
111
|
-
@inheritable_class_vars ||= [:inheritable_class_vars]
|
112
|
-
@inheritable_class_vars += vars
|
113
|
-
end
|
114
|
-
|
115
|
-
# Builds the attr_reader and attr_writer of `attrs` and registers
|
116
|
-
# the associated instance variable as inheritable.
|
117
|
-
def inheritable_attrs(*attrs)
|
118
|
-
attrs.each do |attr|
|
119
|
-
class_eval %(
|
120
|
-
class << self; attr_accessor :#{attr} end
|
121
|
-
), __FILE__, __LINE__ - 2
|
122
|
-
end
|
123
|
-
|
124
|
-
inheritable_class_vars(*attrs)
|
125
|
-
end
|
126
|
-
|
127
|
-
# This callback method is called whenever a subclass of the current class is created.
|
128
|
-
# @note
|
129
|
-
# - values of the instance variables are copied as they are (no dups or clones)
|
130
|
-
# - the above means: avoid methods that change the state of the mutable object on it
|
131
|
-
# - mutating methods would reflect the changes on other classes as well
|
132
|
-
# - therefore, `freeze` will be called on the values that are inherited.
|
133
|
-
def inherited(subclass)
|
134
|
-
super
|
135
|
-
inheritable_class_vars.each do |var|
|
136
|
-
instance_var = instance_variable_name(var)
|
137
|
-
value = instance_variable_get(instance_var)
|
138
|
-
subclass.instance_variable_set(instance_var, value.freeze)
|
139
|
-
end
|
140
|
-
end
|
5
|
+
include Eco::Language::Klass::HelpersBuilt
|
141
6
|
end
|
142
7
|
end
|
143
8
|
end
|
@@ -1,8 +1,7 @@
|
|
1
1
|
class Eco::API::Common::Loaders::Config
|
2
|
-
|
3
|
-
extend Eco::Language::Methods::DelegateMissing
|
2
|
+
include Eco::Language::Delegation::DelegatingMissingOnClass
|
4
3
|
|
5
|
-
|
4
|
+
delegating_missing_on_class_to :config
|
6
5
|
|
7
6
|
class << self
|
8
7
|
# To create samples of configurations
|
@@ -29,8 +28,6 @@ class Eco::API::Common::Loaders::Config
|
|
29
28
|
config.active_enviro
|
30
29
|
end
|
31
30
|
end
|
32
|
-
|
33
|
-
delegate_missing_to :config
|
34
31
|
end
|
35
32
|
|
36
33
|
require_relative 'config/cli'
|
@@ -118,6 +118,7 @@ module Eco
|
|
118
118
|
end
|
119
119
|
|
120
120
|
# Upload a file to the specific `remote_folder`
|
121
|
+
# @return [String, FalseClass] on success returns the remote file path.
|
121
122
|
def upload(local_file, remote_folder:, gid: nil)
|
122
123
|
return false unless local_file && File.exist?(local_file)
|
123
124
|
|
@@ -133,9 +134,15 @@ module Eco
|
|
133
134
|
end
|
134
135
|
|
135
136
|
log(:info) {
|
136
|
-
"Uploaded '#{local_file}' (#{res})"
|
137
|
+
"Uploaded '#{local_file}' as '#{dest_file}' (#{res})"
|
137
138
|
}
|
138
|
-
|
139
|
+
|
140
|
+
dest_file
|
141
|
+
rescue StandardError
|
142
|
+
log(:error) {
|
143
|
+
"Could not upload file '#{dest_file}' (#{res})"
|
144
|
+
}
|
145
|
+
raise
|
139
146
|
end
|
140
147
|
|
141
148
|
private
|
@@ -8,6 +8,7 @@ module Eco::API::UseCases::Lib::Files
|
|
8
8
|
|
9
9
|
private
|
10
10
|
|
11
|
+
# @return [String, FalseClass] the path of the remote file or `false` if failed.
|
11
12
|
def upload(local_file, subfolder: remote_subfolder, gid: sftp_group_id)
|
12
13
|
sftp_session.upload(
|
13
14
|
local_file,
|
@@ -34,15 +35,19 @@ module Eco::API::UseCases::Lib::Files
|
|
34
35
|
subfolder: remote_subfolder,
|
35
36
|
pattern: nil,
|
36
37
|
local_folder: self.local_folder,
|
38
|
+
only_latest: false,
|
37
39
|
&block
|
38
40
|
)
|
39
41
|
remote_files = with_remote_files(subfolder: subfolder, pattern: pattern)
|
40
|
-
|
42
|
+
|
43
|
+
return [] if remote_files.empty?
|
44
|
+
remote_files = [remote_files.first] if only_latest
|
41
45
|
|
42
46
|
file_names = remote_files.map {|file| to_remote_path(file.name, subfolder: subfolder)}
|
43
47
|
|
44
48
|
log(:info) {
|
45
|
-
msg = "Getting the following files into the local folder
|
49
|
+
msg = "Getting the following files into the local folder "
|
50
|
+
msg << "'#{local_folder || '.'}':\n"
|
46
51
|
msg << ' * '
|
47
52
|
msg << file_names.join("\n * ")
|
48
53
|
msg
|
@@ -118,8 +123,6 @@ module Eco::API::UseCases::Lib::Files
|
|
118
123
|
local_dir
|
119
124
|
elsif self.class.const_defined?(:LOCAL_FOLDER)
|
120
125
|
self.class::LOCAL_FOLDER
|
121
|
-
else
|
122
|
-
'.'
|
123
126
|
end
|
124
127
|
end
|
125
128
|
|
@@ -37,7 +37,9 @@ class Eco::API::UseCases::Samples::Drivers::Sftp < Eco::API::Common::Loaders::Us
|
|
37
37
|
|
38
38
|
file_names = files.map {|file| to_remote_path(file.name)}
|
39
39
|
|
40
|
-
|
40
|
+
msg = "Getting the following files into the local folder "
|
41
|
+
msg << "'#{local_folder || '.'}':"
|
42
|
+
puts msg
|
41
43
|
puts file_names
|
42
44
|
|
43
45
|
sftp.download(file_names, local_folder: local_folder)
|
data/lib/eco/data/fuzzy_match.rb
CHANGED
@@ -0,0 +1,18 @@
|
|
1
|
+
module Eco::Language::Delegation
|
2
|
+
class ChainableDelegator < SimpleDelegator
|
3
|
+
include ForDelegator::DelegatedClass
|
4
|
+
include ForDelegator::ConstDelegator
|
5
|
+
include ForDelegator::ConstLookupHooks
|
6
|
+
|
7
|
+
# It allows to chain delegators, when the first parameter is an
|
8
|
+
# instance of `delegated_class`.
|
9
|
+
# @note it also allows to create an instance of `delegated_class`
|
10
|
+
# on initialization.
|
11
|
+
def initialize(*args, **kargs, &block)
|
12
|
+
obj = args.first
|
13
|
+
obj = new(*args, **kargs, &block) unless of_kind?(obj)
|
14
|
+
|
15
|
+
super(obj)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# rubocop:disable Naming/MethodParameterName
|
2
|
+
|
3
|
+
module Eco::Language::Delegation
|
4
|
+
module DelegatingMissing
|
5
|
+
class << self
|
6
|
+
def included(base)
|
7
|
+
super
|
8
|
+
|
9
|
+
base.extend Eco::Language::Klass::HelpersBuilt
|
10
|
+
base.extend ClassMethods
|
11
|
+
base.inheritable_class_vars :_delegating_missing, :delegating_missing_to
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
module ClassMethods
|
16
|
+
def delegating_missing(*these, to:)
|
17
|
+
msg = "Delegating to: should be String or Symbol. Given: #{to.class}"
|
18
|
+
raise ArgumentError, msg unless sym_or_string?(to)
|
19
|
+
|
20
|
+
these.map do |this|
|
21
|
+
msg = "Expecting String or Symbol. Given: #{this}."
|
22
|
+
raise ArgumentError, msg unless sym_or_string?(this)
|
23
|
+
|
24
|
+
this.to_sym
|
25
|
+
end.each do |this|
|
26
|
+
_delegating_missing[this] = to
|
27
|
+
end
|
28
|
+
|
29
|
+
self
|
30
|
+
end
|
31
|
+
|
32
|
+
def delegating_missing_to(to = nil)
|
33
|
+
return @delegating_missing_to if to.nil?
|
34
|
+
|
35
|
+
msg = "Expecting String or Symbol. Given: #{to}."
|
36
|
+
raise ArgumentError, msg unless sym_or_string?(to)
|
37
|
+
|
38
|
+
|
39
|
+
@delegating_missing_to = to.to_sym
|
40
|
+
end
|
41
|
+
|
42
|
+
def delegating_missing?(sym)
|
43
|
+
return true if sym.nil? && delegating_missing_to
|
44
|
+
return false unless sym_or_string?(sym)
|
45
|
+
return true if _delegating_missing.key?(sym.to_sym)
|
46
|
+
return true if delegating_missing_to
|
47
|
+
|
48
|
+
false
|
49
|
+
end
|
50
|
+
|
51
|
+
def delegating_missing_target(instance, at: nil)
|
52
|
+
return unless delegating_missing?(at)
|
53
|
+
return unless (subject_ref = _delegating_missing[at] || delegating_missing_to)
|
54
|
+
|
55
|
+
instance_has_method =
|
56
|
+
instance.methods.include?(subject_ref) ||
|
57
|
+
instance.private_methods.include?(subject_ref)
|
58
|
+
|
59
|
+
return instance.method(subject_ref).call if instance_has_method
|
60
|
+
return unless at.to_s.start_with?('@')
|
61
|
+
return unless instance.instance_variable_defined?(at)
|
62
|
+
|
63
|
+
instance.instance_variable_get(at)
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def _delegating_missing
|
69
|
+
@_delegating_missing ||= {}
|
70
|
+
end
|
71
|
+
|
72
|
+
def sym_or_string?(value)
|
73
|
+
return false unless value.is_a?(Symbol) || value.is_a?(String)
|
74
|
+
return false if value.to_s.strip.empty?
|
75
|
+
|
76
|
+
true
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# INSTANCE Methods
|
81
|
+
|
82
|
+
def respond_to_missing?(method_name, include_private = false)
|
83
|
+
super
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
# @note if missing, redirect all parameters to `receiver`,
|
89
|
+
# as long as responds_to `method_name`
|
90
|
+
def method_missing(method_name, *args, **kargs, &block)
|
91
|
+
return super unless self.class.delegating_missing?(method_name)
|
92
|
+
|
93
|
+
target = self.class.delegating_missing_target(self, at: method_name)
|
94
|
+
|
95
|
+
if method_name.to_s.start_with?('@')
|
96
|
+
target.instance_variable_get(method_name)
|
97
|
+
else
|
98
|
+
target.send(method_name, *args, **kargs, &block)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# rubocop:enable Naming/MethodParameterName
|