class Mobj::Token
Public Class Methods
new(type, *args)
click to toggle source
# File lib/mobj.rb, line 17 def initialize(type, *args) @type, @path, @options = type.to_sym, nil, {} tokens = [] args.each do |arg| if arg.h? @options.merge!(arg) elsif arg.s? tokens << arg.sym else tokens << arg end end @path = tokens.sequester! end
Public Instance Methods
extract(obj, path)
click to toggle source
# File lib/mobj.rb, line 34 def extract(obj, path) obj.__mobj__reparent if path == :* || obj.nil? obj elsif obj.a? if path[0] == '*' && obj.respond_to?(path[1..-1].sym) obj.__send__(path[1..-1].sym) else obj.map { |o| extract(o, path) } end elsif path.a? path.map { |pth| obj[pth.sym] } elsif path[0] == '*' && obj.respond_to?(path[1..-1].sym) obj.__send__(path[1..-1].sym) elsif obj.respond_to?(:[]) && (obj.h? || path.to_s =~ /[0-9.-]+/) if obj.h? obj[path.sym] else obj[path.to_s.to_i] if path.to_s =~ /^\d+$/ end elsif obj.respond_to?(path.sym) obj.__send__(path.sym) else nil end end
find(obj, match)
click to toggle source
# File lib/mobj.rb, line 61 def find(obj, match) if obj.a? obj.map do |child| find(child, match) end elsif obj.respond_to?(:keys) found = obj.keys.each.with_object({}) { |key, fnd| m = key.to_s.match(match) fnd[key] = m if m } flat = found.values.flat_map(&:captures).empty? found.each.with_object(flat ? [] : {}) { |(key, m), map| if map.a? map << obj[key] else named = m.to_h.invert name = if named.empty? m.captures.empty? ? key : m.captures.sequester! else named.find { |k, v| !k.nil? }.attempt(key).last end map[name] = obj[key] end } end end
to_s()
click to toggle source
# File lib/mobj.rb, line 32 def to_s() "#{@type.to_s.upcase}(#@path#{ " => #@options" unless @options.empty?})" end
walk(obj, root = obj)
click to toggle source
# File lib/mobj.rb, line 91 def walk(obj, root = obj) obj, root = Circle.wrap!(obj), Circle.wrap!(root) val = case @type when :literal @path.to_s when :path extract(obj, @path) when :regex find(obj, @path) when :up if obj.respond_to? :parent obj.__mobj__parent || obj.__mobj__parent else obj.__mobj__parent end when :any if obj.a? obj.map { |o| walk(o, root) } else @path.return_first { |token| token.walk(obj, root) } end when :all matches = @path.map { |token| token.walk(obj, root) } matches.compact.size == @path.size ? matches : nil when :each @path.map { |token| token.walk(obj, root) } when :lookup lookup = @path.walk(obj) if lookup.a? lookup.flatten.map { |lu| lu.tokenize.walk(root) }.flatten(1) else lookup.tokenize.walk(root) end when :inverse raise "not implemented yet. not sure how to implement yet, actually. please continue to hold. your call is important to us." when :root tree = [@path].flatten while (path = tree.shift) obj = path.walk(obj) end obj.a? ? obj.flatten : obj end val = @options[:indexes] ? val.values_at(*@options[:indexes]) : val val end