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