Module: Eco::Language
- Included in:
- Assets::Language
- Defined in:
- lib/eco/language.rb,
lib/eco/language/curry.rb,
lib/eco/language/klass.rb,
lib/eco/language/match.rb,
lib/eco/language/models.rb,
lib/eco/language/methods.rb,
lib/eco/language/values_at.rb,
lib/eco/language/models/wrap.rb,
lib/eco/language/basic_logger.rb,
lib/eco/language/hash_transform.rb,
lib/eco/language/match_modifier.rb,
lib/eco/language/auxiliar_logger.rb,
lib/eco/language/models/modifier.rb,
lib/eco/language/methods/dsl_able.rb,
lib/eco/language/models/collection.rb,
lib/eco/language/klass/when_inherited.rb,
lib/eco/language/models/class_helpers.rb,
lib/eco/language/methods/call_detector.rb,
lib/eco/language/hash_transform_modifier.rb,
lib/eco/language/methods/delegate_missing.rb,
lib/eco/language/models/parser_serializer.rb
Defined Under Namespace
Modules: AuxiliarLogger, Klass, Methods, Models, Test Classes: BasicLogger, HashTransformModifier, MatchModifier
Class Method Summary collapse
Instance Method Summary collapse
- #curry(method) ⇒ Object
-
#get_accessor(object, attr, accessors: []) ⇒ Object
adapted from: https://stackoverflow.com/a/16908153/4352306.
- #hash_transform(hash, mode = HashTransformModifier.new) ⇒ Object
- #match?(value, at, mode = MatchModifier.new, depth: 0) ⇒ Boolean
- #required_parameters(method) ⇒ Object
- #required_parameters?(method) ⇒ Boolean
- #stringify_hash(hash, mode = HashTransformModifier.new) ⇒ Object
- #stringify_keys(hash, mode = HashTransformModifier.new) ⇒ Object
- #stringify_values(hash, mode = HashTransformModifier.new) ⇒ Object
- #sym_str_transform(value, mode = HashTransformModifier.new) ⇒ Object
- #symbolize_hash(hash, mode = HashTransformModifier.new) ⇒ Object
- #symbolize_keys(hash, mode = HashTransformModifier.new) ⇒ Object
- #symbolize_values(hash, mode = HashTransformModifier.new) ⇒ Object
- #to_key(pr) ⇒ Object
- #to_value(pr) ⇒ Object
- #values_at(object, *attrs, **kattrs) ⇒ Object
-
#values_at_dot(object, *attrs, curry: false, debug: false, **kattrs) ⇒ Object
enables dot notation to do object nesting access.
Class Method Details
.test_values_at ⇒ Object
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/eco/language/values_at.rb', line 142 def self.test_values_at h = {'pops' => 'aghr!', pops: 5, 'nops' => 'nope!'} a = Test::A.new('hello!') b = Test::B.new('bye') b.c = 'cheese' pp Handy.values_at(h, 'nops', :pops) pp Handy.values_at(a, 'rops', 'mops', rops: 'EVERY', xops: ['Dear', xop: 'SOMETHING BETTER']) pp Handy.values_at(a, 'mops', 'gops', rops: 'EVERY THING') pp Handy.values_at_dot(b, 'c', 'bofs' => ['stranberry', v2: 'combines'], 'a.rops': 'DOTTED CALL') pp "+" * 60 pp Handy.values_at_dot(b, 'c', 'bofs' => ['stranberry', v2: 'combines'], debug: true, 'a.rops': 'DOTTED CALL') pp "+" * 60 end |
Instance Method Details
#curry(method) ⇒ Object
12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# File 'lib/eco/language/curry.rb', line 12 def curry(method) -> (*args, **kargs) { required = method.parameters.select { |type, _| type == :req } krequired = method.parameters.select { |type, _| type == :keyreq } all_args = (required.length <= args.length) all_keys = krequired.all? { |_, name| kargs.has_key?(name) } if all_args && all_keys final_args = (args + kargs.map {|k,v| {k => v} }) method.call(*final_args) else -> (*args_, **kargs_) { curry(method)[*args, *args_, **kargs, **kargs_] } end } end |
#get_accessor(object, attr, accessors: []) ⇒ Object
adapted from: https://stackoverflow.com/a/16908153/4352306
35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/eco/language/values_at.rb', line 35 def get_accessor(object, attr, accessors: []) accessors.push( ->(obj, att) { object.method(att) } ) #accessors.push( ->(obj, att) { object[att] } ) accessors.reduce(nil) { |chosen, acc| chosen ? chosen : (acc[object, attr] && acc rescue nil) || chosen } #accessors.reduce(nil) { |chosen, acc| # puts "attr: #{attr} => current: #{acc}" # chosen ? chosen : (acc[object, attr] && acc rescue nil) || chosen # puts "attr: #{attr} => after check - chosen: #{chosen}" # chosen # } end |
#hash_transform(hash, mode = HashTransformModifier.new) ⇒ Object
25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/eco/language/hash_transform.rb', line 25 def hash_transform(hash, mode = HashTransformModifier.new) hash = (mode.clone?) ? Marshal.load(Marshal.dump(hash)) : hash hash.keys.each do |key| value = (mode.keys?) ? hash.delete(key) : hash[key] value = (value.is_a?(Hash) && mode.recurse?) ? hash_transform(value, mode) : value value = sym_str_transform(value, mode) if mode.values? key = sym_str_transform(key, mode) if mode.keys? hash[key] = value end hash end |
#match?(value, at, mode = MatchModifier.new, depth: 0) ⇒ Boolean
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/eco/language/match.rb', line 4 def match?(value, at, mode = MatchModifier.new, depth: 0) out_match = ->(v) { match?(v, at, mode, depth: depth + 1) } in_match = ->(a) { match?(value, a, mode, depth: depth + 1) } indent_msg = ->(m) { puts (" " * depth) + m if mode.debug? } case when mode.reverse? indent_msg.call("reverse value #{value} <--> at: #{at}") match?(at , value, mode.new.reset_reverse, depth: depth + 1) when mode.pattern? indent_msg.call("at to pattern: #{at}") at = mode.to_regex(at) match?(value, at, mode.new.reset_pattern, depth: depth + 1) when value.is_a?(Array) indent_msg.call("array #{value} value.#{mode.any?? "any?" : "all?"} match(v_item, at) at: #{at}") return value.any?(&out_match) if mode.any? value.all?(&out_match) # defaults to EVERY when at.is_a?(Array) indent_msg.call("array #{at} at.#{mode.and?? "all?" : "any?"} match(value, at_item). value: #{value}") return at.all?(&in_match) if mode.and? at.any?(&in_match) # defaullts to OR when at.is_a?(Regexp) indent_msg.call("(#{at.inspect}) at.match?(value); value: #{value}") at.match?(value) when value.is_a?(Regexp) indent_msg.call("(#{value.inspect}) value.match?(at); at: #{at}") value.match?(at) else # final compare indent_msg.call("-- final -- mode: #{mode.to_a}; value: #{value}; at: #{at}") m = (value == at) || (mode.insensitive? && at&.downcase == value&.downcase) (mode.not?) ? !m : m end end |
#required_parameters(method) ⇒ Object
4 5 6 |
# File 'lib/eco/language/curry.rb', line 4 def required_parameters(method) method.parameters.select { |type, _| type == :req || :keyreq} end |
#required_parameters?(method) ⇒ Boolean
8 9 10 |
# File 'lib/eco/language/curry.rb', line 8 def required_parameters?(method) required_parameters(method).length > 0 end |
#stringify_hash(hash, mode = HashTransformModifier.new) ⇒ Object
62 63 64 65 |
# File 'lib/eco/language/hash_transform.rb', line 62 def stringify_hash(hash, mode = HashTransformModifier.new) mode = mode.new.stringify.keys.values hash_transform(hash, mode) end |
#stringify_keys(hash, mode = HashTransformModifier.new) ⇒ Object
42 43 44 45 |
# File 'lib/eco/language/hash_transform.rb', line 42 def stringify_keys(hash, mode = HashTransformModifier.new) mode = mode.new.stringify.keys hash_transform(hash, mode) end |
#stringify_values(hash, mode = HashTransformModifier.new) ⇒ Object
52 53 54 55 |
# File 'lib/eco/language/hash_transform.rb', line 52 def stringify_values(hash, mode = HashTransformModifier.new) mode = mode.new.stringify.values hash_transform(hash, mode) end |
#sym_str_transform(value, mode = HashTransformModifier.new) ⇒ Object
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# File 'lib/eco/language/hash_transform.rb', line 4 def sym_str_transform(value, mode = HashTransformModifier.new) v = value if value && (value.is_a?(Symbol) || value.is_a?(String)) if mode.symbolize? && !value.is_a?(Symbol) colon = mode.colon? && !value.include?(" ") && ( starts = value.start_with?(":") || ends = value.end_with?(":") ) if !mode.colon? || colon value = value.slice(1, value.length) if colon && starts value = value.slice(0, -1) if colon && ends v = (value.to_sym rescue value) || value end elsif !value.is_a?(String) # stringify v = (value.to_s rescue value) || value v = ":" + v if mode.colon? end end v end |
#symbolize_hash(hash, mode = HashTransformModifier.new) ⇒ Object
57 58 59 60 |
# File 'lib/eco/language/hash_transform.rb', line 57 def symbolize_hash(hash, mode = HashTransformModifier.new) mode = mode.new.symbolize.keys.values hash_transform(hash, mode) end |
#symbolize_keys(hash, mode = HashTransformModifier.new) ⇒ Object
37 38 39 40 |
# File 'lib/eco/language/hash_transform.rb', line 37 def symbolize_keys(hash, mode = HashTransformModifier.new) mode = mode.new.symbolize.keys hash_transform(hash, mode) end |
#symbolize_values(hash, mode = HashTransformModifier.new) ⇒ Object
47 48 49 50 |
# File 'lib/eco/language/hash_transform.rb', line 47 def symbolize_values(hash, mode = HashTransformModifier.new) mode = mode.new.symbolize.values hash_transform(hash, mode) end |
#to_key(pr) ⇒ Object
4 5 6 |
# File 'lib/eco/language/values_at.rb', line 4 def to_key(pr) pr.is_a?(Hash) ? pr.keys.first : pr end |
#to_value(pr) ⇒ Object
8 9 10 |
# File 'lib/eco/language/values_at.rb', line 8 def to_value(pr) pr.is_a?(Hash) ? pr.values.first : pr end |
#values_at(object, *attrs, **kattrs) ⇒ Object
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/eco/language/values_at.rb', line 12 def values_at(object, *attrs, **kattrs) all_params = attrs + kattrs.map {|k,v| {k => v} } return object.values_at(*all_params) if object.is_a?(Hash) all_keys = all_params.map { |pr| to_key(pr) } arguments = all_params.each_with_index.map { |pr, i| pr.values[0] if pr.is_a?(Hash)} #puts "all_keys: #{all_keys}; arguments: #{arguments}" values = all_keys.each_with_index.map do |k, i| a = k; v = [] v = arguments[i] if all_params[i].is_a?(Hash) # with params attr_method = get_accessor(object, a)[object, a] rescue nil #puts "attr: #{a} - method: #{attr_method}" next if !attr_method args = v.is_a?(Array) ? v : [].push(v) attr_method = curry(attr_method) if required_parameters?(attr_method) # final call to the method #puts "args: #{args}" value = attr_method[*args] # rescue nil value = nil if value.is_a?(Proc) value end end |
#values_at_dot(object, *attrs, curry: false, debug: false, **kattrs) ⇒ Object
enables dot notation to do object nesting access
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/eco/language/values_at.rb', line 49 def values_at_dot (object, *attrs, curry: false, debug: false, **kattrs) all_params = attrs + kattrs.map {|k,v| {k => v} } return object.values_at(*all_params) if object.is_a?(Hash) to_s = ->(k) { ((k.to_s rescue k) || key) } to_sym = ->(k) { ((k.to_sym rescue k) || key) } dotted = ->(k) { to_s[k].include?('.') } pdotted = ->(pr) { dotted[to_key(pr)] } haccess = ->(dp) { # prepare call k = dp k, v = [dp.keys.first, dp.values.first] if (hash = dp.is_a?(Hash)) kf, kr = [ (ss = to_s[k].split('.')).first , ss.slice(1)] nxt_cll = hash ? {kr => v} : kr {k => {'a' => kf, 'v' => nxt_cll }} } all_keys = all_params.map { |pr| to_key(pr) } hash_params = all_params.reduce({}) { |h,pr| h.merge!(pr) if pr.is_a?(Hash); h } dot_params = all_params.select { |pr| pdotted[pr] } dot_keys = dot_params.map { |dp| to_key(dp) } dot_wrappers = dot_params.reduce({}) { |h,dp| h.merge(haccess[dp]) } if debug pp "object : #{object}" pp "all_params: #{all_params}" pp "dot_keys : #{dot_keys}" end values = all_keys.map do |k| a = k; v = [] puts "key: #{k}" if debug case true when dot_keys.include?(k) # dotted (recursive) dot = dot_wrappers[k] a, v = dot.values_at('a', 'v') when hash_params.key?(k) # no dotted, with params v = hash_params[k] end attr_method = get_accessor(object, a)[object, a] rescue nil next if !attr_method args = v.is_a?(Array) ? v : [].push(v) attr_method = curry(attr_method) if required_parameters?(attr_method) if dot_keys.include?(k) # recurse (dotted) args.push({ curry: curry, debug: debug }) value = values_at(attr_method.call, *args).first else # final call to the method value = attr_method[*args] # rescue nil puts "value: #{value}" if debug end value = nil if !curry && value.is_a?(Proc) value end end |