Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are there something like Python generators in Ruby?

I am new to Ruby, is there a way to yield values from Ruby functions? If yes, how? If not, what are my options to write lazy code?

like image 657
bodacydo Avatar asked Mar 23 '10 23:03

bodacydo


People also ask

Does Ruby have generators?

Ruby provides a script called Generator. This script can be used to generate many useful items in Rails.

Why generators are better in Python?

Generators allow you to create iterators in a very pythonic manner. Iterators allow lazy evaluation, only generating the next element of an iterable object when requested. This is useful for very large data sets. Iterators and generators can only be iterated over once.

Are Python generators efficient?

In Python, yield is a keyword that turns a function into a generator. Unlike a list, a generator does not store values. Instead, it knows the current value and how to get the next one. This makes a generator memory-efficient.

What is a Python generator?

Python generators are a simple way of creating iterators. All the work we mentioned above are automatically handled by generators in Python. Simply speaking, a generator is a function that returns an object (iterator) which we can iterate over (one value at a time).


2 Answers

Ruby's yield keyword is something very different from the Python keyword with the same name, so don't be confused by it. Ruby's yield keyword is syntactic sugar for calling a block associated with a method.

The closest equivalent is Ruby's Enumerator class. For example, the equivalent of the Python:

def eternal_sequence():   i = 0   while True:     yield i     i += 1 

is this:

def eternal_sequence   Enumerator.new do |enum|     i = 0     while true       enum.yield i # <- Notice that this is the yield method of the enumerator, not the yield keyword       i +=1     end   end end 

You can also create Enumerators for existing enumeration methods with enum_for. For example, ('a'..'z').enum_for(:each_with_index) gives you an enumerator of the lowercase letters along with their place in the alphabet. You get this for free with the standard Enumerable methods like each_with_index in 1.9, so you can just write ('a'..'z').each_with_index to get the enumerator.

like image 94
Chuck Avatar answered Sep 23 '22 21:09

Chuck


I've seen Fibers used in that way, look at an example from this article:

fib = Fiber.new do     x, y = 0, 1    loop do       Fiber.yield y      x,y = y,x+y    end  end  20.times { puts fib.resume } 
like image 31
Michael Kohl Avatar answered Sep 24 '22 21:09

Michael Kohl