4 ms·
Ruby has generators, but it’s not just blocks and yield. Generators are special because after they’ve yielded (in the Python sense) a value, they are actually n
by jcheng 6y ago
Ruby has generators, but it’s not just blocks and yield. Generators are special because after they’ve yielded (in the Python sense) a value, they are actually no longer on the stack at all. But when their next value is requested, they pick up execution right where they left off with all local variables intact, as if they had never suspended execution.
If that doesn’t make sense to you, it’s definitely worth taking a few minutes out to look up some tutorials on generators in Python or any other language that supports them.
In Ruby, you can create a generator by passing a block to Enumerator#new; the block’s parameter is a “yielder” object whose << operator behaves like Python’s yield keyword. Keep in mind that this block is NOT invoked once per iteration; it is invoked once, it might suspend and resume though (or suspend and not resume!).
https://stackoverflow.com/questions/35826375/enumerator-new-and-yield https://stackoverflow.com/questions/35826375/enumerator-new-...
- jonnytran 6y agoYes, the difference is between internal iterators vs. external iterators. For external iterators, Ruby's Enumerator syntax is a little less convenient. But I think it's a small price to pay for not having 2 colors of functions [1]. In Ruby, an Enumerator is just an object with methods like any other object. And there are things built in to core to make working with lazy enumerators just as easy as regular ones. To GP's point, you rarely actually need enumerators because of a block's ability to break in Ruby. It's the most useful thing that's in so few languages [2]. For example, if I really wanted to write an infinite loop yielding fib -- not saying I would do it this way but -- the quickest way to do it in Ruby, adapting the Stack Overflow example, is probably more like this: def fib() puts "Enter function" a = b = 1 i = 0 loop do puts "Inside loop" yield i, a puts "i: #{i}, a: #{a}, b: #{b}" a, b = b, a + b i += 1 end end n_from_user_input = 5 fib do |i, x| break if i == n_from_user_input puts "Use value: #{x}" end 1: https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/ https://journal.stuffwithstuff.com/2015/02/01/what-color-is-... 2: https://yehudakatz.com/2012/01/10/javascript-needs-blocks/ https://yehudakatz.com/2012/01/10/javascript-needs-blocks/