5

Does Ruby provide any mechanism to allow an iterator to yield all values from another iterator? (or "subiterator", I'm not sure what the proper name is). Similar to Python3.3+'s yield from

def f
    yield 'a'
    yield 'b'
end

def g
   # yield everything from f
   yield 'c'
   yield 'd'
end
Ryan Haining
  • 35,360
  • 15
  • 114
  • 174
  • `f { |x| yield x }` too long? :) – Joachim Isaksson Jul 15 '13 at 18:04
  • @JoachimIsaksson if `f` yields multiple values it starts to be – Ryan Haining Jul 15 '13 at 18:33
  • though I suppose {|*x| yield x} be okay but idk if there are any subtleties to that I'm missing. But I was looking for something that handles all the things that can happen in normal interactions with iterators (exceptions and whatnot) without anything special – Ryan Haining Jul 15 '13 at 19:04
  • 2
    `yield` means and does [something different](http://stackoverflow.com/questions/2504494/are-there-something-like-python-generators-in-ruby) in both languages. – steenslag Jul 15 '13 at 19:13
  • I was not aware that yield was equivalent to just calling the block, thanks – Ryan Haining Jul 15 '13 at 22:20

2 Answers2

4

This is probably the most idiomatic approach:

def f
  yield 'a'
  yield 'b'
end

def g(&block)
  f(&block)
  yield 'c'
  yield 'd'
end
tokland
  • 66,169
  • 13
  • 144
  • 170
3

One way is this:

def f
  yield 'a'
  yield 'b'
end

def g
 f &Proc.new # 'duplicate' the block given to g and pass it to f
 yield 'c'
 yield 'd'
end
ichigolas
  • 7,595
  • 27
  • 50
  • I had no idea that was possible. Can you give some reference? why `Proc.new` is the duplicate of the block and not an empty proc? it looks somewhat cryptic at first sight. – tokland Jul 15 '13 at 19:31
  • 2
    The [docs](http://www.ruby-doc.org/core-2.0/Proc.html#method-c-new) specify this behaviour :). – ichigolas Jul 15 '13 at 19:40
  • 1
    That's sad because I searched the docs, read those lines, and failed to connect the dots :-( I am afraid that's just too implicit for my taste. I don't recall finding code that uses "feature" either, so I guess I am not the only one. It perfectly answers the question, though, so +1 – tokland Jul 15 '13 at 19:48
  • Anyone interested in the use of `&` above should check out: http://ablogaboutcode.com/2012/01/04/the-ampersand-operator-in-ruby/ – Jonah Jul 15 '13 at 20:14
  • comparing this to @tokland's answer. Does tokland's avoid duplication of the block, or does the `&block` create a new `Proc` object as well? (Ruby's far from my strongest language) – Ryan Haining Jul 15 '13 at 22:45
  • 1
    @Ryan I tested that just now. It seems like neither methods duplicate the block. The blocks have same hash. – ichigolas Jul 16 '13 at 13:58