Reliably remove nodes from owned sets.
The combination of iterating over an array and removing values from it results in not all elements being removed. For example: numbers = [10, 20, 30] numbers.each do |num| numbers.delete(num) end numbers # => [20] As a result of this the NodeSet#remove method uses two iterations: 1. One iteration to retrieve all NodeSet instances to remove nodes from. 2. One iteration to actually remove the nodes. For the second iteration we iterate over the node sets and then over the nodes. This ensures that we always remove all nodes instead of leaving some behind.
This commit is contained in:
parent
5073056831
commit
30845e3d65
|
@ -166,9 +166,21 @@ module Oga
|
|||
# This method is intended to remove nodes from an XML document/node.
|
||||
#
|
||||
def remove
|
||||
sets = []
|
||||
|
||||
# First we gather all the sets to remove nodse from, then we remove the
|
||||
# actual nodes. This is done as you can not reliably remove elements
|
||||
# from an Array while iterating on that same Array.
|
||||
@nodes.each do |node|
|
||||
node.node_set.delete(node)
|
||||
node.node_set = nil
|
||||
if node.node_set
|
||||
sets << node.node_set
|
||||
|
||||
node.node_set = nil
|
||||
end
|
||||
end
|
||||
|
||||
sets.each do |set|
|
||||
@nodes.each { |node| set.delete(node) }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -213,6 +213,12 @@ describe Oga::XML::NodeSet do
|
|||
@n1.node_set.nil?.should == true
|
||||
@n2.node_set.nil?.should == true
|
||||
end
|
||||
|
||||
example 'remove all nodes from the owned set' do
|
||||
@doc_set.remove
|
||||
|
||||
@doc_set.empty?.should == true
|
||||
end
|
||||
end
|
||||
|
||||
context '#delete' do
|
||||
|
|
Loading…
Reference in New Issue