From: Robert Klemme Date: 2010-10-21T01:45:17+09:00 Subject: Re: about handling args in block On 20.10.2010 16:35, Jeremy Bopp wrote: > On 10/20/2010 9:16 AM, salamond wrote: >> Hi, guys. >> >> I'm writing a Node class for a Binary Tree. >> Coding comes below. >> >> There's a method remove_leaf. >> Now I want to do it this way: >> =begin >> [@left_node, @right_node].each do |node| >> if node.is_leaf? >> node = nil >> end >> end >> =end >> >> But it doesn't work. >> Is there a way to do it ? > > In your example, node is just a reference to the same objects referenced > by @left_node and @right_node. Assigning nil to node only discards the > reference held by node. It looks like you're trying to do this too much > the C/C++ way, where you would have a pointer to a pointer that you > could then nullify. > > The alternative code you're already using (where you unrolled this loop) > is probably the easiest and most straightforward way to deal with this > issue. OP, you can somewhat simplify the code Node = Struct.new :value, :left, :right do # We usually do not use prefix "is" which # you might be used to in Java. def leaf? @left.nil? && @right.nil? end # Actually this will remove all leaves hence the # changed name. def remove_leaves self.left = nil if left && left.leaf? self.right = nil if right && right.leaf? self end def to_s; value.to_s end # Useful for recursive algorithms. def visit(val = nil, &b) val = @left.visit(val, &b) if @left val = b[self, val] val = @right.visit(val, &b) if @right val end end :-) Have fun! Btw, you original implementation had a flaw because it would break if a Node had only one child. For the other the test ".is_leaf?" would fail because NilClass does not have that method. Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/