Ruby's yield
не является итератором, как в C # и Python. yield
само по себе является действительно простой концепцией, если вы понимаете, как работают блоки в Ruby.
Да, блоки - это функциональная функция программирования, хотя Ruby не является функциональным языком. Фактически, Ruby использует метод lambda
для создания блочных объектов, который заимствован из синтаксиса Lisp для создания анонимных функций, то есть блоков. С точки зрения информатики, блоки Руби (и лямбда-функции Лиспа) замыкания . В Ruby методы обычно занимают только один блок. (Вы можете пройти больше, но это неловко.)
Ключевое слово yield
в Ruby - это просто способ вызова блока, переданного методу. Эти два примера эквивалентны:
def with_log
output = yield # We're calling our block here with yield
puts "Returned value is #{output}"
end
def with_log(&stuff_to_do) # the & tells Ruby to convert into
# an object without calling lambda
output = stuff_to_do.call # We're explicitly calling the block here
puts "Returned value is #{output}"
end
В первом случае мы просто предполагаем, что есть блок, и говорим, чтобы вызвать его. В другом случае Ruby оборачивает блок в объект и передает его в качестве аргумента. Первый более эффективен и удобочитаем, но в действительности он одинаков. Вы бы назвали любой из них так:
with_log do
a = 5
other_num = gets.to_i
@my_var = a + other_num
end
И будет напечатано значение, которое в итоге будет присвоено @my_var
. (Хорошо, так что это совершенно глупая функция, но я думаю, вы поняли идею.)
Блоки используются во многих вещах в Ruby. Почти в каждом месте, где вы бы использовали цикл в языке, подобном Java, он заменяется в Ruby методами, которые принимают блоки. Например,
[1,2,3].each {|value| print value} # prints "123"
[1,2,3].map {|value| 2**value} # returns [2, 4, 8]
[1,2,3].reject {|value| value % 2 == 0} # returns [1, 3]
Как заметил Эндрю, он также широко используется для открытия файлов и во многих других местах. В основном, когда у вас есть стандартная функция, которая может использовать некоторую пользовательскую логику (например, сортировку массива или обработку файла), вы будете использовать блок. Есть и другие применения, но этот ответ уже так долго, я боюсь, что это вызовет сердечные приступы у читателей с более слабыми конституциями. Надеюсь, это прояснит путаницу в этой теме.