Extended maintenance of Ruby versions 1.8.7 and 1.9.2 ended on July 31, 2014. Read more
YAML Generic Model container
We want the node to act like as Hash if it is.
# File yaml/basenode.rb, line 185 def []( *key ) if Hash === @value v = @value.detect { |k,| k.transform == key.first } v[1] if v elsif Array === @value @value.[]( *key ) end end
# File yaml/basenode.rb, line 69 def at( seg ) if Hash === @value self[seg] elsif Array === @value and seg =~ /\A\d+\Z/ and @value[seg.to_i] @value[seg.to_i] end end
# File yaml/basenode.rb, line 194 def children if Hash === @value @value.values.collect { |c| c[1] } elsif Array === @value @value end end
# File yaml/basenode.rb, line 202 def children_with_index if Hash === @value @value.keys.collect { |i| [self[i], i] } elsif Array === @value i = -1; @value.collect { |v| i += 1; [v, i] } end end
YPath search returning a complete depth array
# File yaml/basenode.rb, line 80 def match_path( ypath_str ) depth = 0 matches = [] YPath.each_path( ypath_str ) do |ypath| seg = match_segment( ypath, 0 ) matches += seg if seg end matches.uniq end
Search a node for a single YPath segment
# File yaml/basenode.rb, line 93 def match_segment( ypath, depth ) deep_nodes = [] seg = ypath.segments[ depth ] if seg == "/" unless String === @value idx = -1 @value.collect { |v| idx += 1 if Hash === @value match_init = [v[0].transform, v[1]] match_deep = v[1].match_segment( ypath, depth ) else match_init = [idx, v] match_deep = v.match_segment( ypath, depth ) end if match_deep match_deep.each { |m| deep_nodes.push( match_init + m ) } end } end depth += 1 seg = ypath.segments[ depth ] end match_nodes = case seg when "." [[nil, self]] when ".." [["..", nil]] when "*" if @value.is_a? Enumerable idx = -1 @value.collect { |h| idx += 1 if Hash === @value [h[0].transform, h[1]] else [idx, h] end } end else if seg =~ /^"(.*)"$/ seg = $1 elsif seg =~ /^'(.*)'$/ seg = $1 end if ( v = at( seg ) ) [[ seg, v ]] end end return deep_nodes unless match_nodes pred = ypath.predicates[ depth ] if pred case pred when /^\.=/ pred = $' # ' match_nodes.reject! { |n| n.last.value != pred } else match_nodes.reject! { |n| n.last.at( pred ).nil? } end end return match_nodes + deep_nodes unless ypath.segments.length > depth + 1 #puts "DEPTH: #{depth + 1}" deep_nodes = [] match_nodes.each { |n| if n[1].is_a? BaseNode match_deep = n[1].match_segment( ypath, depth + 1 ) if match_deep match_deep.each { |m| deep_nodes.push( n + m ) } end else deep_nodes = [] end } deep_nodes = nil if deep_nodes.length == 0 deep_nodes end
Search for YPath entry and return a list of qualified paths.
# File yaml/basenode.rb, line 55 def search( ypath_str ) matches = match_path( ypath_str ) if matches matches.collect { |m| path = [] m.each_index { |i| path.push m[i] if ( i % 2 ).zero? } "/" + path.compact.join( "/" ) } end end
Search for YPath entry and return qualified nodes.
# File yaml/basenode.rb, line 17 def select( ypath_str ) matches = match_path( ypath_str ) # # Create a new generic view of the elements selected # if matches result = [] matches.each { |m| result.push m.last } YAML.transfer( 'seq', result ) end end
Search for YPath entry and return transformed nodes.
# File yaml/basenode.rb, line 36 def select!( ypath_str ) matches = match_path( ypath_str ) # # Create a new generic view of the elements selected # if matches result = [] matches.each { |m| result.push m.last.transform } result end end