どうもこんにちは。
今回は、RubyGoldで出てきそうなProc
とlambda
についてまとめました。
Proc
とlambda
の比較表
もう先に比較表を載せておきます。
特徴 | lambda | Proc |
---|---|---|
引数のチェック | 厳格にチェック。引数が不足または過剰だとエラー | 引数の数に寛容。足りない場合はnilを補完する |
returnの動作 | lambda内でのみ終了し、呼び出し元に戻る | 呼び出し元全体からreturnする |
作成方法の違い | lambdaまたは->で定義 | Proc.newで定義 |
lambda
lambda
の基本構文
lambda
を使うことで、引数を受け取る無名関数を作成できます。以下は、lambda
の一般的な構文です。
my_lambda = lambda { |x, y| x + y }
または、短縮形で->(ラムダリテラル)を使うこともできます。
my_lambda = ->(x, y) { x + y }
lambda
の使い方
定義したlambda
は、call
メソッドを使って実行します。引数はcall
メソッドに渡します。
例
my_lambda = ->(x, y) { x + y }
result = my_lambda.call(2, 3)
puts result #=> 5
result = my_lambda.call()
puts result #=> エラー: wrong number of arguments (given 1, expected 2)
Proc
Proc
の基本構文
Proc
を使用した無名関数を定義する場合は、new
メソッドを使用してProc
クラスのインスタンスを作って定義します。
my_proc = Proc.new { |x, y| x + y }
Proc
の使い方
lambda
と同様で、call
メソッドを使って実行します。
my_proc = Proc.new { |x, y| x + y }
result = my_proc.call(2, 3)
puts result #=> 5
result = my_proc.call(2)
puts result # => nil(yがnilとして扱われ、計算結果がnil)
Proc
とlambda
内でのreturn
動作
Proc
の場合
Proc
内で実行されたreturn
は、Proc
の中身だけじゃなくてそのProc
を含むメソッド全体を終了させます。今回で言うと、return
が実行されるProc
の含まれるtest_proc
メソッド全体の処理が終了します。
def test_proc
my_proc = Proc.new { return "Inside proc" }
my_proc.call
return "Outside proc"
end
puts test_proc # => "Inside proc"(Procが呼び出し元のメソッドも終了させる)
lambda
の場合
lambda
の場合は、lambda
内で実行されたreturn
はlambda
内でしか効力を発揮できません。
そのため、test_lambda
メソッドは継続して実行されます。
def test_lambda
my_lambda = -> { return "Inside lambda" }
my_lambda.call
return "Outside lambda"
end
puts test_lambda # => "Outside lambda"(lambda内でのみ処理が終了し、呼び出し元に影響しない)
まとめ
Rails開発する人は、lambda
を使うと割と簡潔にメソッドを定義できたりするので覚えておくと良いと思います。
モデルで以下のように定義しておくと...
app/models/sample.rb
class Sample < ApplicationRecord
active = -> { where(destroy_flag: false) }
end
いろんなところで、メソッドを呼び出せます。
class SamplesController < ApplicationController
def index
@samples = Sample.active
end
end