2010-03-23 7 views

risposta

43

Ruby's yield parola chiave è qualcosa di molto diverso dalla parola chiave Python con lo stesso nome, quindi non essere confuso da esso. La parola chiave yield di Ruby è zucchero sintattico per chiamare un blocco associato a un metodo.

L'equivalente più vicino è la classe Enumeratore di Ruby. Ad esempio, l'equivalente del Python:

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

è questo:

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 

È inoltre possibile creare enumeratori per i metodi di enumerazione esistente con enum_for. Ad esempio, ('a'..'z').enum_for(:each_with_index) fornisce un enumeratore delle lettere minuscole insieme al loro posto nell'alfabeto. Puoi ottenerlo gratuitamente con i metodi Enumerable standard come each_with_index in 1.9, quindi puoi semplicemente scrivere ('a'..'z').each_with_index per ottenere l'enumeratore.

+2

'0.step' è un enumeratore eterna dal 1.9 – steenslag

21

ho visto Fibers utilizzato in quel modo, guardare un esempio dalla 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 } 
+6

Infatti, in Ruby 1.9 del' Enumerator' è implementato utilizzando 'Fiber'. Questo è stato uno dei motivi principali per aggiungerli, in realtà, perché in Ruby 1.8 'gli Enumerator usano le continuazioni, ma questo è un) piuttosto ingombrante eb) in quel momento le versioni successive sarebbero state rimosse dal linguaggio Ruby. –

10

Se siete alla ricerca di generare pigramente valori, @ risposta di Chuck è quella corretta.

Se si sta cercando di scorrere lentamente su una raccolta, Ruby 2.0 ha introdotto il nuovo enumeratore .lazy.

range = 1..Float::INFINITY 
puts range.map { |x| x+1 }.first(10) # infinite loop 
puts range.lazy.map { |x| x+1 }.first(10) # [2, 3, 4, 5, 6, 7, 8, 9, 10, 11]