yieldは、メソッドに渡されたブロックを呼び出します — 制御をブロックに譲り、オプションで値を渡してからメソッドを再開します。これはメソッドが与えられたブロックを呼び出す方法であり、Rubyの反復処理と多くの洗練されたパターンの背後にあるメカニズムです。
基本的なyield — 与えられたブロックを呼び出す
puts
puts
greet { puts }
メソッドがyieldを呼び出すと、それに渡されたブロック({ }またはdo...end内)が実行されます。メソッドは、ブロックが実行されるいつ(そして何回)かをコントロールします。
def each_pair
yield("a", 1) # pass values to the block's parameters
yield("b", 2)
end
each_pair { |key, value| puts "#{key}: #{value}" }
# Output: a: 1 / b: 2
yield(args)はブロックのパラメータ(|key, value|)に値を渡します — これが反復処理メソッドが各要素をブロックに与える方法です。
def my_each(array)
i = 0
while i < array.length
yield(array[i]) # yield each element to the block
i += 1
end
end
my_each([1, 2, 3]) { |n| puts n * 2 } # 2, 4, 6
# this is essentially how Array#each works internally!
これはRubyの反復処理メソッド(each、mapなど)が内部でどのように機能するかを示しています — 各要素をブロックにyieldします。
def maybe_yield
if block_given? # check whether a block was passed (avoid an error)
yield
else
"no block"
end
end
# explicitly capture the block as a parameter (with &)
def run(&block) # &block captures the block as a Proc object
block.call # call it explicitly
end
block_given?はブロックが渡されたかを確認します(LocalJumpErrorを回避するため)、そして&blockはブロックをProcオブジェクトとしてキャプチャして、保存または転送できるようにします。
yieldを理解することは、重要なRubyの知識です — これはメソッドがブロックを呼び出す仕組みであり、Rubyの特徴的な反復処理と多くの洗練されたパターンを支えているため、それを把握することでRubyがどのように実際に機能するのかが明らかになります。yieldは、メソッドに渡されたブロックを呼び出し(それに制御を譲り、オプションで値を渡す)、これはまさにRubyの反復処理メソッド(each、map、select)が内部で動作する方法です — 各要素をブロックにyieldします。
これを理解することで、Rubyのブロックベースの反復処理が明確になり、ブロックを受け入れる独自のメソッドを作成することができます — 表現力豊かなAPI、カスタム反復処理、リソース管理メソッド(ブロックの前後のセットアップ/ティアダウン)、およびDSLを作成するための強力な機能です。
yield(ブロックを呼び出し、引数を渡す)、block_given?(ブロックが渡されたかを安全に確認し、エラーを回避する)、および&block(ブロックをProcとして明示的にキャプチャする)を知ることは、Rubyの反復処理とブロック受け入れメソッドがどのように機能するのかを理解し、独自のブロックベースメソッドを記述するために重要です。
ブロックはRubyの中核であり、yieldがメソッドがそれらを使う方法であるため、yieldを理解することでRubyの最も特徴的な機能(ブロック)への理解が深まり、Rubyを表現力豊かにする洗練されたブロック受け入れメソッドを作成できるようになります — クリーンなAPIを構築するための貴重なスキルであり、Rubyのブロック機構が実際にはどのように機能するのかについての理解を反映する一般的なインタビューのトピックです。