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
@@ -0,0 +1,53 @@
|
|
1
|
+
module Eco::Language::Delegation
|
2
|
+
# Class to lookup constants through `delegated_class`.
|
3
|
+
# @note it uses `DelegatingMissing`.
|
4
|
+
# @note it tries to lookup on the `class` of the `delegating_missing_to`
|
5
|
+
# object. Which requires an instance of the delegator to exist, with
|
6
|
+
# the aim of scoping its class (so it can chain constant lookup), unless
|
7
|
+
# `delegated_class` is explicitly stated.
|
8
|
+
# @note that not setting `delegated_class` explicitly could fail
|
9
|
+
# to chain the looup.
|
10
|
+
module DelegatingMissingConst
|
11
|
+
class << self
|
12
|
+
def included(base)
|
13
|
+
super
|
14
|
+
|
15
|
+
base.send :include, DelegatingMissing
|
16
|
+
base.send :include, ForDelegator::ConstDelegator
|
17
|
+
base.extend ClassMethods
|
18
|
+
|
19
|
+
# because we inject `#initialize`
|
20
|
+
base.send :prepend, InstanceMethods
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
module ClassMethods
|
25
|
+
# Set always `delegated_class` when fetching the
|
26
|
+
# `delegating_missing_to` object.
|
27
|
+
def delegating_missing_target(instance, at: nil)
|
28
|
+
super.tap do |target|
|
29
|
+
next unless target
|
30
|
+
next unless at.nil?
|
31
|
+
|
32
|
+
delegated_class target.class
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
module InstanceMethods
|
38
|
+
# Set the `delegated_class` to chain **constant lookup**
|
39
|
+
# via `delegating_missing_to.class`.
|
40
|
+
# @note this requires that the target can be fetched without passing
|
41
|
+
# parameters (as it is typically the case with `delegating_missing_to`).
|
42
|
+
def initialize(...)
|
43
|
+
super if defined?(super)
|
44
|
+
|
45
|
+
delegated_class.tap do |klass|
|
46
|
+
next unless (target = self.class.delegating_missing_target(self))
|
47
|
+
|
48
|
+
self.class.delegated_class target.class
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Eco::Language::Delegation
|
2
|
+
module DelegatingMissingOnClass
|
3
|
+
class << self
|
4
|
+
def included(base)
|
5
|
+
super
|
6
|
+
|
7
|
+
base.extend Eco::Language::Klass::HelpersBuilt
|
8
|
+
base.extend ClassMethods
|
9
|
+
base.inheritable_class_vars :delegating_missing_on_class_to
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
module ClassMethods
|
14
|
+
def delegating_missing_on_class_to(to = nil)
|
15
|
+
return @delegating_missing_on_class_to if to.nil?
|
16
|
+
|
17
|
+
msg = "Expecting String or Symbol. Given: #{to}."
|
18
|
+
raise ArgumentError, msg unless sym_or_string?(to)
|
19
|
+
|
20
|
+
@delegating_missing_on_class_to = to
|
21
|
+
end
|
22
|
+
|
23
|
+
def respond_to_missing?(method_name, include_private = false)
|
24
|
+
super
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
# @note if missing, redirect all parameters to `target`,
|
30
|
+
# as long as responds_to `method_name`
|
31
|
+
def method_missing(method_name, *args, **kargs, &block)
|
32
|
+
return super unless (target = delegating_missing_on_class_target)
|
33
|
+
|
34
|
+
target.send(method_name, *args, **kargs, &block)
|
35
|
+
end
|
36
|
+
|
37
|
+
# retrieves the delegating_missing_on_class_to object
|
38
|
+
def delegating_missing_on_class_target
|
39
|
+
return unless @delegating_missing_on_class_to
|
40
|
+
|
41
|
+
# fetch the object behind the method
|
42
|
+
method(@delegating_missing_on_class_to).call
|
43
|
+
end
|
44
|
+
|
45
|
+
def sym_or_string?(value)
|
46
|
+
return false unless value.is_a?(Symbol) || value.is_a?(String)
|
47
|
+
return false if value.to_s.strip.empty?
|
48
|
+
|
49
|
+
true
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -1,7 +1,9 @@
|
|
1
|
-
module Eco::Language::Delegation
|
1
|
+
module Eco::Language::Delegation::ForDelegator
|
2
2
|
# Module that is to be used with ruby `Delegator` or related helpers,
|
3
3
|
# such as `SimpleDelegator` or `Forwardable`.
|
4
|
-
# @note
|
4
|
+
# @note
|
5
|
+
# 1. It includes `DelegatedClass`
|
6
|
+
# 2. This class only provides lookups integration.
|
5
7
|
# @note it looks up the constant via `delegated_class`. This is because
|
6
8
|
# on `Delegator` approaches, the intance object (`self`) points to the
|
7
9
|
# delegated object, which doesn't allow to refer to `self.class` to
|
@@ -15,13 +17,13 @@ module Eco::Language::Delegation
|
|
15
17
|
def included(base)
|
16
18
|
super
|
17
19
|
|
18
|
-
base.send :include,
|
19
|
-
base.extend
|
20
|
+
base.send :include, DelegatedClass
|
21
|
+
base.extend ClassMethods
|
20
22
|
end
|
21
23
|
end
|
22
24
|
|
23
25
|
module ClassMethods
|
24
|
-
def const_defined?(str, inherit = true, delegated: true)
|
26
|
+
def const_defined?(str, inherit = true, delegated: true) # rubocop:disable Style/OptionalBooleanParameter
|
25
27
|
return super(str, inherit) if super(str, inherit) || !delegated
|
26
28
|
return true if delegated_class&.const_defined?(str, inherit)
|
27
29
|
|
@@ -41,7 +43,7 @@ module Eco::Language::Delegation
|
|
41
43
|
const_get(str)
|
42
44
|
end
|
43
45
|
|
44
|
-
def constants(inherited = true, delegated: true)
|
46
|
+
def constants(inherited = true, delegated: true) # rubocop:disable Style/OptionalBooleanParameter
|
45
47
|
super(inherited).dup.tap do |consts|
|
46
48
|
next unless delegated && delegated_class
|
47
49
|
|
data/lib/eco/language/delegation/{const_lookup_hooks.rb → for_delegator/const_lookup_hooks.rb}
RENAMED
@@ -1,6 +1,8 @@
|
|
1
|
-
module Eco::Language::Delegation
|
1
|
+
module Eco::Language::Delegation::ForDelegator
|
2
2
|
# This approach only makes sense to be used in `Delegator` and related helpers.
|
3
|
-
# @note
|
3
|
+
# @note
|
4
|
+
# 1. It includes `ConstDelegator` (which includes `DelegatedClass`).
|
5
|
+
# 2. This class installs new instance methods.
|
4
6
|
# @note for each not inherited constant that isn't part of the delegated object's
|
5
7
|
# class, it will create a undercore/snake named instance method, to ease
|
6
8
|
# constant lookup througout chained/wrapped delegators.
|
@@ -11,22 +13,49 @@ module Eco::Language::Delegation
|
|
11
13
|
def included(base)
|
12
14
|
super
|
13
15
|
|
14
|
-
|
16
|
+
msg = 'Only to be included in Delegator subclasses (i.e. SimpleDelegator). '
|
17
|
+
msg << 'As this concern is just a work around to not being possible to fetch '
|
18
|
+
msg << 'the Decorator class, because self.class refers to the class of the '
|
19
|
+
msg << 'decorated object. Meaning that it is not necessary on other patterns.'
|
20
|
+
raise ArgumentError, msg unless base <= Delegator
|
15
21
|
|
16
|
-
base.
|
22
|
+
base.send :include, ConstDelegator
|
23
|
+
|
24
|
+
base.extend ClassMethods
|
17
25
|
base.send :install_constant_lookup_hooks
|
18
26
|
end
|
19
27
|
end
|
20
28
|
|
21
29
|
module ClassMethods
|
30
|
+
include Eco::Language::Strings::Underscore
|
31
|
+
|
32
|
+
# @note
|
33
|
+
# - We don't install const hook methods when `delegated_class` is (re)defined,
|
34
|
+
# because these hooks aim only the delegator (not the delegated).
|
35
|
+
# @todo **However**It is still to be seen if we should include this concern
|
36
|
+
# to the `delegated_class`, provided that const lookup methods are aligned
|
37
|
+
# (as it is a requirement).
|
38
|
+
# When `delegated_class` is **defined**, install const hook methods too it.
|
39
|
+
# def delegated_class(klass = nil)
|
40
|
+
# super.tap do
|
41
|
+
# next if klass.nil?
|
42
|
+
# next if klass < ConstLookupHooks
|
43
|
+
|
44
|
+
# klass.send :include, ConstLookupHooks
|
45
|
+
# end
|
46
|
+
# end
|
47
|
+
|
22
48
|
private
|
23
49
|
|
50
|
+
# When **inherited**, install const hook methods to the `subclass`.
|
24
51
|
def inherited(subclass)
|
25
52
|
super
|
26
53
|
|
27
54
|
subclass.send :install_constant_lookup_hooks
|
28
55
|
end
|
29
56
|
|
57
|
+
# When a constant is **added** install const hook methods to it.
|
58
|
+
# to the `subclass`.
|
30
59
|
def const_added(sym)
|
31
60
|
install_constant_lookup_hook(const: sym)
|
32
61
|
end
|
@@ -45,6 +74,7 @@ module Eco::Language::Delegation
|
|
45
74
|
end
|
46
75
|
end
|
47
76
|
|
77
|
+
# If `base` does NOT have the constant hook method, it defines it.
|
48
78
|
def install_constant_lookup_hook(base = self, const:)
|
49
79
|
meth_name = underscore(const).to_sym
|
50
80
|
return if instance_method?(base, name: meth_name, include_private: true)
|
@@ -58,18 +88,6 @@ module Eco::Language::Delegation
|
|
58
88
|
base.define_method(meth_name, &method_def)
|
59
89
|
end
|
60
90
|
|
61
|
-
# @see https://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-underscore
|
62
|
-
def underscore(sym)
|
63
|
-
return super if defined?(super)
|
64
|
-
return sym.to_s.dup unless /[A-Z-]|::/.match?(sym)
|
65
|
-
|
66
|
-
word = sym.to_s.gsub('::', '/')
|
67
|
-
word.gsub!(/(?<=[A-Z])(?=[A-Z][a-z])|(?<=[a-z\d])(?=[A-Z])/, '_')
|
68
|
-
word.tr!('-', '_')
|
69
|
-
word.downcase!
|
70
|
-
word
|
71
|
-
end
|
72
|
-
|
73
91
|
def instance_method?(base = self, name:, include_private: false)
|
74
92
|
return true if base.method_defined?(name)
|
75
93
|
return false unless include_private
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module Eco::Language::Delegation
|
1
|
+
module Eco::Language::Delegation::ForDelegator
|
2
2
|
module DelegatedClass
|
3
3
|
class << self
|
4
4
|
private
|
@@ -6,7 +6,11 @@ module Eco::Language::Delegation
|
|
6
6
|
def included(base)
|
7
7
|
super
|
8
8
|
|
9
|
-
base.extend
|
9
|
+
base.extend Eco::Language::Klass::HelpersBuilt
|
10
|
+
base.extend ClassMethods
|
11
|
+
|
12
|
+
base.inheritable_class_vars :delegated_class
|
13
|
+
|
10
14
|
base.send :patch_class_compare
|
11
15
|
end
|
12
16
|
end
|
@@ -20,12 +24,6 @@ module Eco::Language::Delegation
|
|
20
24
|
|
21
25
|
private
|
22
26
|
|
23
|
-
def inherited(subclass)
|
24
|
-
super
|
25
|
-
|
26
|
-
subclass.instance_variable_set(:@delegated_class, @delegated_class)
|
27
|
-
end
|
28
|
-
|
29
27
|
def patch_class_compare(base = self)
|
30
28
|
%i[< <= ==].each do |op|
|
31
29
|
base.singleton_class.define_method(op) do |other|
|
@@ -40,17 +38,6 @@ module Eco::Language::Delegation
|
|
40
38
|
|
41
39
|
# Instance methods
|
42
40
|
|
43
|
-
# It allows to chain delegators, when the first parameter is an
|
44
|
-
# instance of `delegated_class`.
|
45
|
-
# @note it also allows to create an instance of `delegated_class`
|
46
|
-
# on initialization.
|
47
|
-
def initialize(*args, **kargs, &block)
|
48
|
-
obj = args.first
|
49
|
-
obj = new(*args, **kargs, &block) unless of_kind?(obj)
|
50
|
-
|
51
|
-
super(obj)
|
52
|
-
end
|
53
|
-
|
54
41
|
def delegated_class
|
55
42
|
self.class.delegated_class
|
56
43
|
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'delegate'
|
2
|
+
|
3
|
+
module Eco::Language::Delegation
|
4
|
+
# Helpers to be included on native `Delegator` subclasses.
|
5
|
+
module ForDelegator
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
require_relative 'for_delegator/delegated_class'
|
10
|
+
require_relative 'for_delegator/const_delegator'
|
11
|
+
require_relative 'for_delegator/const_lookup_hooks'
|
@@ -3,6 +3,8 @@ module Eco::Language
|
|
3
3
|
end
|
4
4
|
end
|
5
5
|
|
6
|
-
require_relative 'delegation/
|
7
|
-
require_relative 'delegation/
|
8
|
-
require_relative 'delegation/
|
6
|
+
require_relative 'delegation/for_delegator'
|
7
|
+
require_relative 'delegation/chainable_delegator'
|
8
|
+
require_relative 'delegation/delegating_missing_on_class'
|
9
|
+
require_relative 'delegation/delegating_missing'
|
10
|
+
require_relative 'delegation/delegating_missing_const'
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Eco::Language::Klass
|
2
|
+
module Builder
|
3
|
+
include Resolver
|
4
|
+
include Naming
|
5
|
+
|
6
|
+
# If the class for `name` exists, it returns it. Otherwise it generates it.
|
7
|
+
# @param name [String, Symbol] the name of the new class
|
8
|
+
# @param inherits [Class] the parent class to _inherit_ from
|
9
|
+
# @param parent_space [String] parent namespace of the generated class, if not given: `self`
|
10
|
+
# @yield [child_class] configure the new class
|
11
|
+
# @yieldparam child_class [Class] the new class
|
12
|
+
# @return [Class] the new generated class
|
13
|
+
def new_class(name, inherits:, parent_space: nil)
|
14
|
+
name = name.to_sym.freeze
|
15
|
+
class_name = to_constant(name)
|
16
|
+
parent_space = parent_space ? resolve_class(parent_space) : self
|
17
|
+
full_class_name = "#{parent_space}::#{class_name}"
|
18
|
+
|
19
|
+
unless (target_class = resolve_class(full_class_name, exception: false))
|
20
|
+
target_class = Class.new(inherits)
|
21
|
+
parent_space.const_set class_name, target_class
|
22
|
+
end
|
23
|
+
|
24
|
+
target_class.tap do |klass|
|
25
|
+
yield(klass) if block_given?
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Eco::Language::Klass
|
2
|
+
module Hierarchy
|
3
|
+
# Finds all child classes of the current class.
|
4
|
+
# @param parent_class [Class] the parent class we want to find children of.
|
5
|
+
# @param direct [Boolean] it will only include direct child classes.
|
6
|
+
# @param scope [nil, Array] to only look for descendants among the ones in `scope`.
|
7
|
+
# @return [Arrary<Class>] the child classes in hierarchy order.
|
8
|
+
def descendants(parent_class: self, direct: false, scope: nil)
|
9
|
+
scope ||= ObjectSpace.each_object(::Class)
|
10
|
+
return [] if scope.empty?
|
11
|
+
|
12
|
+
scope.select do |klass|
|
13
|
+
klass < parent_class
|
14
|
+
end.sort do |k_1, k_2|
|
15
|
+
next -1 if k_2 < k_1
|
16
|
+
next 1 if k_1 < k_2
|
17
|
+
0
|
18
|
+
end.tap do |siblings|
|
19
|
+
next unless direct
|
20
|
+
|
21
|
+
siblings.reject! do |si|
|
22
|
+
siblings.any? {|s| si < s}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# @param parent_class [Class] the parent class we want to find children of.
|
28
|
+
# @param direct [Boolean] it will only include direct child classes.
|
29
|
+
# @return [Boolean] `true` if the current class has child classes, and `false` otherwise.
|
30
|
+
def descendants?(parent_class: self, direct: false)
|
31
|
+
descendants(parent_class: parent_class, direct: direct).length.positive?
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Eco::Language::Klass
|
2
|
+
module InheritableClassVars
|
3
|
+
include Naming
|
4
|
+
|
5
|
+
# Keeps track on class instance variables that should be inherited by child classes.
|
6
|
+
# @note
|
7
|
+
# - subclasses will inherit the value as is at that moment
|
8
|
+
# - any change afterwards will be only on the specific class (in line with class instance variables)
|
9
|
+
# - adapted from https://stackoverflow.com/a/10729812/4352306
|
10
|
+
# TODO: this separates the logic of the method to the instance var.
|
11
|
+
# Think if would be possible to join them somehow.
|
12
|
+
def inheritable_class_vars(*vars)
|
13
|
+
@inheritable_class_vars ||= [:inheritable_class_vars]
|
14
|
+
@inheritable_class_vars += vars
|
15
|
+
end
|
16
|
+
|
17
|
+
# Builds the attr_reader and attr_writer of `attrs` and registers
|
18
|
+
# the associated instance variable as inheritable.
|
19
|
+
def inheritable_attrs(*attrs)
|
20
|
+
attrs.each do |attr|
|
21
|
+
class_eval %(
|
22
|
+
class << self; attr_accessor :#{attr} end
|
23
|
+
), __FILE__, __LINE__ - 2
|
24
|
+
end
|
25
|
+
|
26
|
+
inheritable_class_vars(*attrs)
|
27
|
+
end
|
28
|
+
|
29
|
+
# This callback method is called whenever a subclass of the current class is created.
|
30
|
+
# @note
|
31
|
+
# - values of the instance variables are copied as they are (no dups or clones)
|
32
|
+
# - the above means: avoid methods that change the state of the mutable object on it
|
33
|
+
# - mutating methods would reflect the changes on other classes as well
|
34
|
+
# - therefore, `freeze` will be called on the values that are inherited.
|
35
|
+
def inherited(subclass)
|
36
|
+
super
|
37
|
+
|
38
|
+
inheritable_class_vars.each do |var|
|
39
|
+
instance_var = instance_variable_name(var)
|
40
|
+
value = instance_variable_get(instance_var)
|
41
|
+
subclass.instance_variable_set(instance_var, value.freeze)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Eco::Language::Klass
|
2
|
+
module Naming
|
3
|
+
# Helper to normalize `key` into a correct `ruby` **constant name**
|
4
|
+
# @param key [String, Symbol] to be normalized
|
5
|
+
# @return [String] a correct constant name
|
6
|
+
def to_constant(key)
|
7
|
+
key.to_s.strip.split(/[\-\_ ]/i).compact.map do |str|
|
8
|
+
str.slice(0).upcase + str.slice(1..-1).downcase
|
9
|
+
end.join
|
10
|
+
end
|
11
|
+
|
12
|
+
# Helper to create an instance variable `name`
|
13
|
+
# @param [String, Symbol] the name of the variable
|
14
|
+
# @reutrn [String] the name of the created instance variable
|
15
|
+
def instance_variable_name(name)
|
16
|
+
str = name.to_s
|
17
|
+
str = "@#{str}" unless str.start_with?("@")
|
18
|
+
str
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Eco::Language::Klass
|
2
|
+
module Resolver
|
3
|
+
# Creates a class and instance object methods with name `name` to resolve `klass` name
|
4
|
+
def class_resolver(name, klass)
|
5
|
+
define_singleton_method(name) { resolve_class(klass) }
|
6
|
+
define_method(name) { self.class.resolve_class(klass) }
|
7
|
+
end
|
8
|
+
|
9
|
+
# With given a `klass` name it resolves to an actual `Class`
|
10
|
+
# @return [Class] the class that was being searched by name `klass`.
|
11
|
+
def resolve_class(klass, exception: true)
|
12
|
+
@resolved ||= {}
|
13
|
+
@resolved[klass] ||=
|
14
|
+
case klass
|
15
|
+
when Class
|
16
|
+
klass
|
17
|
+
when String
|
18
|
+
begin
|
19
|
+
Kernel.const_get(klass)
|
20
|
+
rescue NameError
|
21
|
+
raise if exception
|
22
|
+
end
|
23
|
+
when Symbol
|
24
|
+
resolve_class(send(klass))
|
25
|
+
else
|
26
|
+
raise "Unknown class: #{klass}" if exception
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -1,18 +1,15 @@
|
|
1
|
-
module Eco
|
2
|
-
module
|
3
|
-
|
4
|
-
|
5
|
-
def inherited(subclass)
|
6
|
-
super
|
7
|
-
subclass.instance_exec(&when_inherited)
|
8
|
-
end
|
1
|
+
module Eco::Language::Klass
|
2
|
+
module WhenInherited
|
3
|
+
def inherited(subclass)
|
4
|
+
super
|
9
5
|
|
10
|
-
|
11
|
-
|
6
|
+
subclass.instance_exec(&when_inherited)
|
7
|
+
end
|
8
|
+
|
9
|
+
def when_inherited(&block)
|
10
|
+
return @when_inherited unless block_given?
|
12
11
|
|
13
|
-
|
14
|
-
end
|
15
|
-
end
|
12
|
+
@when_inherited = block
|
16
13
|
end
|
17
14
|
end
|
18
15
|
end
|
data/lib/eco/language/klass.rb
CHANGED
@@ -5,4 +5,10 @@ module Eco
|
|
5
5
|
end
|
6
6
|
end
|
7
7
|
|
8
|
+
require_relative 'klass/resolver'
|
9
|
+
require_relative 'klass/naming'
|
10
|
+
require_relative 'klass/builder'
|
11
|
+
require_relative 'klass/hierarchy'
|
8
12
|
require_relative 'klass/when_inherited'
|
13
|
+
require_relative 'klass/inheritable_class_vars'
|
14
|
+
require_relative 'klass/helpers_built'
|
data/lib/eco/language/methods.rb
CHANGED
@@ -0,0 +1,17 @@
|
|
1
|
+
module Eco::Language::Strings
|
2
|
+
module Underscore
|
3
|
+
private
|
4
|
+
|
5
|
+
# @see https://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-underscore
|
6
|
+
def underscore(sym)
|
7
|
+
return super if defined?(super)
|
8
|
+
return sym.to_s.dup unless /[A-Z-]|::/.match?(sym)
|
9
|
+
|
10
|
+
word = sym.to_s.gsub('::', '/')
|
11
|
+
word.gsub!(/(?<=[A-Z])(?=[A-Z][a-z])|(?<=[a-z\d])(?=[A-Z])/, '_')
|
12
|
+
word.tr!('-', '_')
|
13
|
+
word.downcase!
|
14
|
+
word
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/eco/language.rb
CHANGED
data/lib/eco/version.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: eco-helpers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.
|
4
|
+
version: 3.0.28
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Oscar Segura
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-03-
|
11
|
+
date: 2025-03-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: byebug
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: rake
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -987,18 +1001,28 @@ files:
|
|
987
1001
|
- lib/eco/language/basic_logger.rb
|
988
1002
|
- lib/eco/language/curry.rb
|
989
1003
|
- lib/eco/language/delegation.rb
|
990
|
-
- lib/eco/language/delegation/
|
991
|
-
- lib/eco/language/delegation/
|
992
|
-
- lib/eco/language/delegation/
|
1004
|
+
- lib/eco/language/delegation/chainable_delegator.rb
|
1005
|
+
- lib/eco/language/delegation/delegating_missing.rb
|
1006
|
+
- lib/eco/language/delegation/delegating_missing_const.rb
|
1007
|
+
- lib/eco/language/delegation/delegating_missing_on_class.rb
|
1008
|
+
- lib/eco/language/delegation/for_delegator.rb
|
1009
|
+
- lib/eco/language/delegation/for_delegator/const_delegator.rb
|
1010
|
+
- lib/eco/language/delegation/for_delegator/const_lookup_hooks.rb
|
1011
|
+
- lib/eco/language/delegation/for_delegator/delegated_class.rb
|
993
1012
|
- lib/eco/language/hash_transform.rb
|
994
1013
|
- lib/eco/language/hash_transform_modifier.rb
|
995
1014
|
- lib/eco/language/klass.rb
|
1015
|
+
- lib/eco/language/klass/builder.rb
|
1016
|
+
- lib/eco/language/klass/helpers_built.rb
|
1017
|
+
- lib/eco/language/klass/hierarchy.rb
|
1018
|
+
- lib/eco/language/klass/inheritable_class_vars.rb
|
1019
|
+
- lib/eco/language/klass/naming.rb
|
1020
|
+
- lib/eco/language/klass/resolver.rb
|
996
1021
|
- lib/eco/language/klass/when_inherited.rb
|
997
1022
|
- lib/eco/language/match.rb
|
998
1023
|
- lib/eco/language/match_modifier.rb
|
999
1024
|
- lib/eco/language/methods.rb
|
1000
1025
|
- lib/eco/language/methods/call_detector.rb
|
1001
|
-
- lib/eco/language/methods/delegate_missing.rb
|
1002
1026
|
- lib/eco/language/methods/dsl_able.rb
|
1003
1027
|
- lib/eco/language/models.rb
|
1004
1028
|
- lib/eco/language/models/class_helpers.rb
|
@@ -1006,6 +1030,8 @@ files:
|
|
1006
1030
|
- lib/eco/language/models/modifier.rb
|
1007
1031
|
- lib/eco/language/models/parser_serializer.rb
|
1008
1032
|
- lib/eco/language/models/wrap.rb
|
1033
|
+
- lib/eco/language/strings.rb
|
1034
|
+
- lib/eco/language/strings/underscore.rb
|
1009
1035
|
- lib/eco/language/values_at.rb
|
1010
1036
|
- lib/eco/version.rb
|
1011
1037
|
homepage: https://www.ecoportal.com
|