Hello --

On Sat, 13 Apr 2002, Pete McBreen wrote:

> Brad Cox wrote
>
> >I need to enumerate the parentage chain of the nodes in a
> >doubly-linked tree. No problem in C/Java, but I'm still too new to
> >Ruby to see how. Can someone help?
>
>
> I though that this one would be easy to answer until I realized that
> although there is a #block_given? method I don't know how to refer to an
> anonymous given block. A very crude hack is to say
>
> class Node
>   def initialize(parent, children=[])
>    @parent = parent
>    @children = children
>    @children.each { |child| child.parent(self) }
>  end
>  def parents (*unused_args, &block)
>    @parent.parents &block unless @parent.nil?
>    yield self
>   end
> end
>
> p = Node.new(nil)
> p2 = Node.new(p)
>
> p2.parents {|o| p o}

I don't think that's such a hack.  Actually, until 1.6.6, the block
was actually propagated upward automatically, so in < 1.6.6 you can do
this:

  def parents(*args)
    yield self
    @parent.parents(*args) if @parent
  end

That no longer happens, so you have to snag the block.  (I know there
was some discussion of the question of automatic block propagation,
and why this change was made, but my ruby-talk search skills seem to
be on vacation this morning.)

Note that if you want to pass the *args up too, then the block has to
be in the arglist:

  def parents(*args,&block)
    yield self
    @parent.parents(*args,&block) if @parent
  end

"@parent.parents(*args) &block", which I tried first, gave me a
no-block error.  Again, I'm pretty sure there was discussion of all of
this -- I just can't find it right now, which is too bad because I
seem to forget and have to relearn the fine points of this
periodically....

(BTW, I'm yielding self first, just to get most-recent-first order.)


David

-- 
David Alan Black
home: dblack / candle.superlink.net
work: blackdav / shu.edu
Web:  http://pirate.shu.edu/~blackdav