# Yield/block question

**URL:** <https://www.ruby-forum.com/t/yield-block-question/148172>\
**Category:** Ruby\
**Created:** [September 10, 2008, 2:11am UTC](https://www.ruby-forum.com/t/yield-block-question/148172 "2008-09-10T02:11:40Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Kenneth\_McDonald](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/dc4da7/32.png) [@Kenneth\_McDonald](https://www.ruby-forum.com/u/Kenneth_McDonald)\
**Post date:** [September 10, 2008, 2:11am UTC](https://www.ruby-forum.com/t/yield-block-question/148172/1 "2008-09-10T02:11:40Z")

</div>

This is something I know how to do in Python, but it’s got me  
flummoxed in Ruby–I still haven’t fully gotten my head around the  
Ruby way. (“yield” means something very different in Python and in Ruby.

Let’s say I have a data structure consisting of nested Arrays and  
numbers, for example [[1,2], 3, [[4]]]. I want to write an extension  
to Array, “each\_leaf”, which takes a block that will be applied to  
each number sequentially in that nested array. For example, if arr is  
the given array, then

result = 0  
arr.each\_leaf {|n| result += n}

would end with result being equal to 1+2+3+4

Could anyone help out? Much appreciated.

Thanks,  
Ken

---

<div class="post-metadata">

**Author:** ![Kenneth\_McDonald](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/dc4da7/32.png) [@Kenneth\_McDonald](https://www.ruby-forum.com/u/Kenneth_McDonald)\
**Post date:** [September 10, 2008, 2:18am UTC](https://www.ruby-forum.com/t/yield-block-question/148172/2 "2008-09-10T02:18:06Z")

</div>

On Tue, Sep 9, 2008 at 5:04 PM, Kenneth McDonald  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> result = 0  
> arr.each\_leaf {|n| result += n}
> 
> would end with result being equal to 1+2+3+4
> 
> Could anyone help out? Much appreciated.

array.flatten.each {|i| yield i}

martin

---

<div class="post-metadata">

**Author:** ![Kenneth\_McDonald](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/dc4da7/32.png) [@Kenneth\_McDonald](https://www.ruby-forum.com/u/Kenneth_McDonald)\
**Post date:** [September 10, 2008, 2:24am UTC](https://www.ruby-forum.com/t/yield-block-question/148172/3 "2008-09-10T02:24:32Z")

</div>

What about this?

class Array  
def each\_leaf(&block)  
each do |x|  
case x  
when Array: x.each\_leaf &block  
else block.call x  
end  
end  
end  
end

arr = [[1,2], 3, [[4]]]  
result = 0  
arr.each\_leaf{|n| result += n}

puts result

Kind regards,

Serabe

P.D. Sorry for no more explanation, but I’m really tired (2:23 am right  
now).

---

<div class="post-metadata">

**Author:** ![Kenneth\_McDonald](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/dc4da7/32.png) [@Kenneth\_McDonald](https://www.ruby-forum.com/u/Kenneth_McDonald)\
**Post date:** [September 10, 2008, 2:44am UTC](https://www.ruby-forum.com/t/yield-block-question/148172/4 "2008-09-10T02:44:25Z")

</div>

Perfect, just what I was looking for. Thanks,  
Ken

---

<div class="post-metadata">

**Author:** ![Kenneth\_McDonald](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/dc4da7/32.png) [@Kenneth\_McDonald](https://www.ruby-forum.com/u/Kenneth_McDonald)\
**Post date:** [September 10, 2008, 2:43am UTC](https://www.ruby-forum.com/t/yield-block-question/148172/5 "2008-09-10T02:43:50Z")

</div>

Very elegant, with the drawback that it requires flattening a  
potentially large array structure.  
But that was carelessness in my lack of specifications. A nice  
solution, thank you.

Ken

---

<div class="post-metadata">

**Author:** ![Kenneth\_McDonald](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/dc4da7/32.png) [@Kenneth\_McDonald](https://www.ruby-forum.com/u/Kenneth_McDonald)\
**Post date:** [September 10, 2008, 11:47am UTC](https://www.ruby-forum.com/t/yield-block-question/148172/6 "2008-09-10T11:47:18Z")

</div>

2008/9/10 Kenneth McDonald [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

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

This can be generalized to Enumerable. Still a handicap is that this  
does not gracefully deal with structures which are not cycle free.

Just some toying around:

module Enumerable  
def each\_leaf(cl = Object, &b)  
each do |el|  
case el  
when String  
yield el if cl === el  
when Enumerable  
el.each\_leaf(cl, &b)  
when cl  
yield el  
else  
# ignore  
end  
end  
end  
end

Kind regards

robert
