私はRubyを初めて使用しますが、Ruby関数からyield
値を取得する方法はありますか?はいの場合、どのようにですか?そうでない場合、遅延コードを作成するためのオプションは何ですか?
Rubyのyield
キーワードは、同じ名前のPythonキーワードとは大きく異なるため、混同しないでください。Rubyのyield
キーワードはシンタックスシュガーです。メソッドに関連付けられたブロックを呼び出すため。
最も近いものはRubyの列挙子クラスです。たとえば、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
enum_for
を使用して、既存の列挙メソッドの列挙子を作成することもできます。たとえば、('a'..'z').enum_for(:each_with_index)
は、小文字の列挙子とアルファベットの位置を示します。これは、1.9のeach_with_index
のような標準のEnumerableメソッドを使用して無料で取得できるため、('a'..'z').each_with_index
と記述して列挙子を取得できます。
怠惰に値を生成することを探しているなら、@ 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]
Rubyは、Enumerable::Generator
を使用してすぐにジェネレーターをサポートします。
require 'generator'
# Generator from an Enumerable object
g = Generator.new(['A', 'B', 'C', 'Z'])
while g.next?
puts g.next
end
# Generator from a block
g = Generator.new { |g|
for i in 'A'..'C'
g.yield i
end
g.yield 'Z'
}
# The same result as above
while g.next?
puts g.next
end
https://Ruby-doc.org/stdlib-1.8.7/libdoc/generator/rdoc/Generator.html