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
Commenting is here to help enhance the documentation. For example, code samples, or clarification of the documentation.
If you have questions about Ruby or the documentation, please post to one of the Ruby mailing lists. You will get better, faster, help that way.
If you wish to post a correction of the docs, please do so, but also file bug report so that it can be corrected for the next release. Thank you.
If you want to help improve the Ruby documentation, please visit Documenting-ruby.org.