# Libhxml Node#remove! kills each loop and extension to #\<\<

**URL:** <https://www.ruby-forum.com/t/libhxml-node-remove-kills-each-loop-and-extension-to/97581>\
**Category:** Ruby\
**Created:** [July 8, 2006, 3:39am UTC](https://www.ruby-forum.com/t/libhxml-node-remove-kills-each-loop-and-extension-to/97581 "2006-07-08T03:39:52Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [July 8, 2006, 3:39am UTC](https://www.ruby-forum.com/t/libhxml-node-remove-kills-each-loop-and-extension-to/97581/1 "2006-07-08T03:39:52Z")

</div>

hi,

While using #each to loop thru the children of a Node, if I remove a  
node the loop breaks on it’s own.

root.each { |node|  
if XML::Node === node  
node.content = “yep”  
node.remove! if node[‘id’] = “b”  
end  
}

The result is

yep

Would tha tbe a bug? Or something that simply can’t be avoided?

Also, I found this extension to #\<\< to be useful:

class XML::Node  
alias\_method :append, :\<\<  
def \<\<( node )  
if Array === node  
node.each { |n| self.append n }  
else  
super  
end  
end  
end

Thanks,  
T.

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [July 8, 2006, 3:55am UTC](https://www.ruby-forum.com/t/libhxml-node-remove-kills-each-loop-and-extension-to/97581/2 "2006-07-08T03:55:40Z")

</div>

removed\_email\_address@domain.invalid wrote:

> ```
> end
> 
> ```
> 
> end

s/super/append(node)/

T.

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [July 8, 2006, 6:20pm UTC](https://www.ruby-forum.com/t/libhxml-node-remove-kills-each-loop-and-extension-to/97581/3 "2006-07-08T18:20:09Z")

</div>

2006/7/8, removed\_email\_address@domain.invalid [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> ```
> <a id="a">yep</a>
> <c id="c"></c>
> 
> ```
> 
> Would tha tbe a bug? Or something that simply can’t be avoided?

It’s usually a problem to change a container while iterating through  
it. This can generate all sorts of weird effects. It’s generally  
better to rely on this _not_ being possible unless explicitely stated  
(e.g most of Java’s iterators implement remove() which savely removes  
an element while iterating).

In your case I’d either first remove the one you want to get rid of,  
iterate using an index (if that’s possible) or remember objects to  
remove in some kind of container and do the removal after the  
iteration (probably the most efficient solution).

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [July 8, 2006, 7:09pm UTC](https://www.ruby-forum.com/t/libhxml-node-remove-kills-each-loop-and-extension-to/97581/4 "2006-07-08T19:09:32Z")

</div>

PS: Here’s another alternative that might work: use delete\_if to  
iterate and delete those elements you want to get rid of.

root.delete\_if do |node|  
if XML::Node === node  
node.content = “yep”  
node[‘id’] == “b”  
else  
false  
end  
end

Cheers

robert

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [July 8, 2006, 7:28pm UTC](https://www.ruby-forum.com/t/libhxml-node-remove-kills-each-loop-and-extension-to/97581/5 "2006-07-08T19:28:16Z")

</div>

On Jul 8, 2006, at 2:37, removed\_email\_address@domain.invalid wrote:

> ```
> <a id="a">yep</a>
> <c id="c"></c>
> 
> ```
> 
> Would tha tbe a bug? Or something that simply can’t be avoided?

I’m not aware (and couldn’t find) any libhxml - if you meant ruby-  
libxml (which seems likely given the problem), here’s what I figured  
out.

At first, I thought it could be a bug caused by modification to the  
structure you’re iterating over, similar to this:

root = [‘a’,‘b’,‘c’]  
root.each { |node| root.delete(node) if node == “b” }

which will skip over ‘c’ due to the deletion.

But while I was trying to confirm this in libxml, I found behaviour  
that makes me think there’s some more fundamental bug. Redefining a  
variable seemed to have some very odd effects, which I managed to  
reduce to this case:

irb(main):001:0\> require ‘rubygems’ # =\> true  
irb(main):002:0\> require ‘xml/libxml’ # =\> true  
irb(main):003:0\> root = XML::Node.new(“root”) # =\>   
irb(main):004:0\> a = XML::Node.new(“a”) # =\>   
irb(main):005:0\> b = XML::Node.new(“b”) # =\>   
**irb(main):006:0\> root # =\>   
irb(main):007:0\> root \<\< a # =\>**   
**irb(main):008:0\> root**

# everything

=\>   
  
   
irb(main):009:0\> root \<\< b # =\>   
**irb(main):010:0\> root  
=\>**   
   
   
   
**irb(main):011:0\> root = XML::Node.new(“root”) # =\>   
irb(main):012:0\> root # =\>   
irb(main):013:0\> root \<\< a # =\>   
irb(main):014:0\> root  
=\>**   
   
  **# where did _this_ come from?**

(That’s the existing definition of #\<\<, not your extension)

Exiting from the irb session results in a segmentation fault, and  
running the same code outside of irb yields the same apparent results  
(inclusion of ‘b’ where it shouldn’t be), and resulted in a bus  
error. I have the hunch that the C extension isn’t managing memory  
properly, which is confirmed by one of the errors submitted on the  
project page. Maybe this is just my setup (1.8.4 on OSX), but it  
seems to me that the library has enough problems that it’s not quite  
ready for use.

matthew smillie.

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [August 3, 2006, 2:24pm UTC](https://www.ruby-forum.com/t/libhxml-node-remove-kills-each-loop-and-extension-to/97581/6 "2006-08-03T14:24:15Z")

</div>

Matthew S. wrote:

> I’m not aware (and couldn’t find) any libhxml - if you meant ruby-  
> libxml (which seems likely given the problem), here’s what I figured  
> out.

🙂 Yes libxml bindings is indeed what I was refering (h was a typo)

> variable seemed to have some very odd effects, which I managed to  
> reduce to this case:

[snip]

> error. I have the hunch that the C extension isn’t managing memory  
> properly, which is confirmed by one of the errors submitted on the  
> project page. Maybe this is just my setup (1.8.4 on OSX), but it  
> seems to me that the library has enough problems that it’s not quite  
> ready for use.

Thanks matthew. Very enlightening. I decdided to write a xml wrapper  
and create an common interface for either REXML and libxml. That way I  
can use REXML for now and easy switch over when libxml binding are  
fully operational.

T.
