# Passing a block to yield

**URL:** <https://www.ruby-forum.com/t/passing-a-block-to-yield/190808>\
**Category:** Ruby\
**Created:** [June 28, 2010, 2:51pm UTC](https://www.ruby-forum.com/t/passing-a-block-to-yield/190808 "2010-06-28T14:51:25Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![chilaquil](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/fbc32d/32.png) [@chilaquil](https://www.ruby-forum.com/u/chilaquil)\
**Post date:** [June 28, 2010, 2:51pm UTC](https://www.ruby-forum.com/t/passing-a-block-to-yield/190808/1 "2010-06-28T14:51:25Z")

</div>

Hello

I was trying to make an iterator that goes through a simple tree  
structure something like that:

class Node  
…  
def each\_child(&block)  
@children.each { |child| yield(child) { child.each\_child(&block) } }  
end  
…  
end

so i could generate a simple html menu:

puts “

”  
root\_node.each\_child { |node|  
puts “- \<a href=”#{child.link}"\>#{child.title}
"  
unless node.children.empty?  
puts “
”  
yield  
puts “
”  
end  
}  
puts “
”

But it turns out that Ruby syntax prohibits passing blocks to yield. A  
simple workaround is to use block.call instead of yield everywhere.

Is there any good reason for that limitation?

---

<div class="post-metadata">

**Author:** ![chilaquil](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/fbc32d/32.png) [@chilaquil](https://www.ruby-forum.com/u/chilaquil)\
**Post date:** [June 28, 2010, 7:35pm UTC](https://www.ruby-forum.com/t/passing-a-block-to-yield/190808/2 "2010-06-28T19:35:25Z")

</div>

On 28.06.2010 14:52, Andy B. wrote:

> }  
> puts “”
> 
> But it turns out that Ruby syntax prohibits passing blocks to yield. A  
> simple workaround is to use block.call instead of yield everywhere.
> 
> Is there any good reason for that limitation?

There is no point in passing a block to yield because yield implicitly  
calls the block passed to the current method.

I think what you really want is this:

def each\_child(&b)  
b[self] # or b.call(self) or simply yield self  
@children.each {|ch| ch.each\_child(&b)}  
self  
end

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![chilaquil](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/fbc32d/32.png) [@chilaquil](https://www.ruby-forum.com/u/chilaquil)\
**Post date:** [June 28, 2010, 11:32pm UTC](https://www.ruby-forum.com/t/passing-a-block-to-yield/190808/3 "2010-06-28T23:32:28Z")

</div>

> There is no point in passing a block to yield

Maybe there always is a way to avoid using procs and lambdas, but i  
don’t see other easy way in my case (see below).  
Proc#call accepts blocks, why does yield not? It’s almost the same  
thing.

> yield implicitly calls the block  
> passed to the current method.

Thanks for the tip. Forgot that yield belongs to method context only.

> def each\_child(&b)  
> b[self] # or b.call(self) or simply yield self  
> @children.each {|ch| ch.each\_child(&b)}  
> self  
> end

This code will just pass all the elements to a block, there’s no way to  
wrap lower levels into

 tag. I need to control what happens before  
and after each\_child so i have use a number of procs as arguments or do  
this trick with a block.

---

<div class="post-metadata">

**Author:** ![chilaquil](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/fbc32d/32.png) [@chilaquil](https://www.ruby-forum.com/u/chilaquil)\
**Post date:** [June 29, 2010, 12:28am UTC](https://www.ruby-forum.com/t/passing-a-block-to-yield/190808/4 "2010-06-29T00:28:44Z")

</div>

On Mon, Jun 28, 2010 at 7:52 AM, Andy B.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)wrote:

> …  
> puts “”

Looks like you can get it to work by explicitly taking the block, rather  
than trying to yield.

def foo(&block)  
block.call 1 do  
2  
end  
end

foo do |param,&block|  
puts “The param is #{param}”  
puts “The block is #{block.call}”  
end

I checked it on 1.8.7 - 1.9.2, it does not work on 1.8.6, though.

---

<div class="post-metadata">

**Author:** ![chilaquil](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/fbc32d/32.png) [@chilaquil](https://www.ruby-forum.com/u/chilaquil)\
**Post date:** [June 29, 2010, 2:07pm UTC](https://www.ruby-forum.com/t/passing-a-block-to-yield/190808/5 "2010-06-29T14:07:03Z")

</div>

2010/6/28 Andy B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> Thanks for the tip. Forgot that yield belongs to method context only.  
> this trick with a block.  
> This would not be solved by yield accepting a block however. Your  
> problem is more complicated. Basically you have a tree structure and  
> you want to traverse the tree while treating inner nodes and leafs  
> differently. You would need at least two different blocks to do what  
> you want. This kind of problem is typically solved with a visitor  
> pattern [1] or similar solution. Basically you need double dispatch  
> [2] on the node type and on the algorithm type.

In your case you could do

# untested

Child = Struct.new :parent, :info do  
def visit(visitor)  
visitor.child(self)  
end  
end

class Parent \< Child  
def initialize  
@children = []  
end

def visit(visitor)  
visitor.enter\_node(self)  
@children.each {|ch| ch.visit(visitor)}  
visitor.leave\_node(self)  
end  
end

class HtmlPrinter  
def enter\_node(n)  
@indent ? @indent + 1 : 1  
puts “#{indent \* ’ '}

”  
end

def leave\_node(n)  
puts “#{indent \* ’ '}

”  
@indent -= 1  
end

def child(n)  
puts “#{indent \* ’ '}

- #{n.info}
”  
end

end

I hope you get the idea.

Kind regards

robert

[1] [http://en.wikipedia.org/wiki/Visitor\_pattern](http://en.wikipedia.org/wiki/Visitor_pattern)  
[2] [Double dispatch - Wikipedia](http://en.wikipedia.org/wiki/Double_dispatch)
