Rubyにおけるブロック、Proc、Lambdaの基本と違い

Rubyのブロック、Proclambdaは、コードの再利用性と柔軟性を高める重要な機能です。しかし、これらの違いを正確に理解し、適切に使い分けることは初学者にとって難しいことがあります。この記事では、ブロック、Proclambdaの基本的な違いを明確にし、実際のコード例を通してその使い方を学びます。

目次

ブロック、Proc、Lambdaとは何か?

Rubyでは、ブロックはメソッドに渡すことができる一時的なコード片です。これに対し、Procはブロックをオブジェクトとして保存し、再利用可能にするためのクラスです。lambdaProcの一種ですが、引数の扱いや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メソッドの短縮形
ビット演算
安全なナビゲーション演算子

これらの具体的な説明は以下の記事をご覧いただけると理解しやすいのではないかと思います!

それぞれの比較

以下の表は、ブロック、Proclambdaの主な特徴と違いをまとめたものです。

引数の厳密性とは?

特徴ブロックProcLambda
表記方法{ |arg| ... } または do |arg| ... endProc.new { |arg| ... } または proc { |arg| ... }lambda { |arg| ... } または ->(arg) { ... }
引数の厳密性厳密ではない厳密ではない厳密
returnの挙動呼び出し元のメソッドを終了自身のコンテキストを終了自身のコンテキストを終了

実際の使用例

以下のサンプルコードでは、ブロック、Proclambdaの具体的な使い方を示します。

ブロックの例

# 配列の各要素にブロックを適用
[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のブロック、Proclambdaの違いとそれぞれの使用例を紹介しました。これらの違いを理解し、適切に使い分けることで、Rubyプログラミングの柔軟性と表現力を高めることができます。ドキュメントを参照しながら、これらの概念を実践的に活用してみてください。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次