Я новичок в Ruby, есть ли способ от yield
значений от функций Ruby? Если да, то как? Если нет, то каковы мои варианты написания ленивого кода?
Есть ли что-то вроде генераторов Python в Ruby?
Ответ 1
Ключевое слово Ruby yield
- это нечто очень отличное от ключевого слова Python с тем же именем, поэтому не путайте его. Ключевое слово Ruby yield
- синтаксический сахар для вызова блока, связанного с методом.
Ближайшим эквивалентом является класс Ruby Enumerator. Например, эквивалент Python:
def eternal_sequence():
i = 0
while True:
yield i
i += 1
:
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
Вы также можете создать Enumerators для существующих методов перечисления с помощью enum_for
. Например, ('a'..'z').enum_for(:each_with_index)
дает вам перечисление строчных букв вместе со своим местом в алфавите. Вы получаете это бесплатно со стандартными методами Enumerable, такими как each_with_index
в 1.9, поэтому вы можете просто написать ('a'..'z').each_with_index
, чтобы получить перечислитель.
Ответ 2
Я видел Волокна, используемые таким образом, посмотрите на пример из в этой статье:
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 }
Ответ 3
Если вы хотите лениво генерировать значения, то ответ @Chuck правильный.
Если вы хотите лениво перебирать коллекцию, Ruby 2.0 представил новый перечислитель .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]