Rubyのブロック、Proc
、lambda
は、コードの再利用性と柔軟性を高める重要な機能です。しかし、これらの違いを正確に理解し、適切に使い分けることは初学者にとって難しいことがあります。この記事では、ブロック、Proc
、lambda
の基本的な違いを明確にし、実際のコード例を通してその使い方を学びます。
ブロック、Proc、Lambdaとは何か?
Rubyでは、ブロックはメソッドに渡すことができる一時的なコード片です。これに対し、Proc
はブロックをオブジェクトとして保存し、再利用可能にするためのクラスです。lambda
はProc
の一種ですが、引数の扱いやreturn
の挙動が異なります。これらの違いを理解することで、より効率的で読みやすいコードを書くことが可能になります。
ブロックとは?
ブロックとは、do end
あるいは、{} で囲われた部分のことを言います。
do endの場合
3.times do
puts "こんにちは"
end
{}の場合
3.times { puts "こんにちは" }
このとき、do end で囲まれる部分と{}で囲まれる部分、どちらもブロックと言います。
Procとは?
Procはブロックをオブジェクトにしたものです。
Procクラスが存在しており、proc = Proc.new { puts "こんにちは" }
という形でオブジェクトを作ることができます。
このProcオブジェクトは、proc.call
という形で利用することができます。
これは引数がない場合ですが、引数がある場合も同様なことが可能です。
[10, 20, 30].each do |number|
puts number
end
[10, 20, 30].each { |number| puts number }
&によるProc→Blockへの展開
先ほど配列の要素を一つずつProcオブジェクトで利用するとき、以下のようなコードを書きました。
[10, 20, 30].each do |number|
print_number.call(number)
end
このコードは以下のように書き換えることもできます。
[10, 20, 30].each(&print_number)
さて、このコードにおいて&(アンパサンド)は何を意味しているのでしょうか?
rubyの&(アンパサンド)が意味するのは、以下のようなものがあります。
rubyの&(アンパサンド)が表すもの
・ブロックを明示的にパラメータとして渡す
・to_procメソッドの短縮形
・ビット演算
・安全なナビゲーション演算子
これらの具体的な説明は以下の記事をご覧いただけると理解しやすいのではないかと思います!
![](https://faw-nlily.com/wp-content/uploads/2023/11/2-300x169.jpg)
それぞれの比較
以下の表は、ブロック、Proc
、lambda
の主な特徴と違いをまとめたものです。
引数の厳密性とは?
特徴 | ブロック | Proc | Lambda |
---|---|---|---|
表記方法 | { |arg| ... } または do |arg| ... end | Proc.new { |arg| ... } または proc { |arg| ... } | lambda { |arg| ... } または ->(arg) { ... } |
引数の厳密性 | 厳密ではない | 厳密ではない | 厳密 |
return の挙動 | 呼び出し元のメソッドを終了 | 自身のコンテキストを終了 | 自身のコンテキストを終了 |
実際の使用例
以下のサンプルコードでは、ブロック、Proc
、lambda
の具体的な使い方を示します。
ブロックの例
# 配列の各要素にブロックを適用
[1, 2, 3].each do |i|
puts i # 出力: 1 2 3
end
Procの例
# Procオブジェクトの作成と呼び出し
my_proc = Proc.new { |x| puts x * 2 }
my_proc.call(5) # 出力: 10
Lambdaの例
# Lambdaの作成と呼び出し
my_lambda = lambda { |x| puts x * 3 }
my_lambda.call(5) # 出力: 15
まとめ
この記事では、Rubyのブロック、Proc
、lambda
の違いとそれぞれの使用例を紹介しました。これらの違いを理解し、適切に使い分けることで、Rubyプログラミングの柔軟性と表現力を高めることができます。ドキュメントを参照しながら、これらの概念を実践的に活用してみてください。