RubyのProc(プロック)とは?ブロックをオブジェクト化して使いこなそう
Rubyには「ブロック」という便利な仕組みがありますが、
それをオブジェクトとして扱えるようにしたものが「Proc(プロック)」です。
Procを使うと、ブロックを変数に代入したり、メソッドの引数として渡したりできるようになります。
Procとは?
Proc
(または Procオブジェクト
)は、ブロックをオブジェクト化したもので、何度でも呼び出せる再利用可能なコードのかたまりです。
Procオブジェクトの作成方法
hello = Proc.new { puts "こんにちは!" }
hello.call # → こんにちは!
Proc.new
で作成し、call
メソッドで実行します。
->(ラムダリテラル)による作成
greet = ->(name) { puts "こんにちは、#{name}さん!" }
greet.call("さくら") # → こんにちは、さくらさん!
->
を使った書き方は「ラムダ式(lambda)」とも呼ばれます。
Proc.new
とほぼ同じですが、振る舞いに違いがあります(後述)。
Procと引数の扱い
add = Proc.new { |a, b| puts a + b }
add.call(1, 2) # → 3
add.call(10) # → nil + 10 → エラーにはならず nil 扱い(注意!)
Proc
は引数の数が一致しなくてもエラーになりにくいという特徴があります。
これに対し lambda
は引数の数が厳密です。
lambda(ラムダ)との違い
違い | Proc | lambda |
引数の数 | ゆるい(不足してもOK) | 厳密(数が合わないとエラー) |
returnの動作 | 呼び出し元メソッドからも抜ける | lambda内だけで return |
構文 | Proc.new { ... } | -> { ... } または lambda { ... } |
Procをメソッドの引数として使う
def twice(proc)
proc.call
proc.call
end
say = Proc.new { puts "こんにちは" }
twice(say)
# → こんにちは
# → こんにちは
ブロックをProcに変換(&記号)
def greet(&block)
block.call
end
greet { puts "ブロックをProcに変換!" }
&
を使うことで、ブロックを Proc オブジェクトとして受け取ることができます。
この方法を使えば、ブロックを通常の引数のように扱えます。
まとめ
RubyのProc(プロック)は、ブロックをオブジェクトとして扱える便利な仕組みです。
変数に代入したり、メソッドの引数として渡したりすることで、再利用性の高いコードが書けます。
まずは Proc.new
や ->
を使って、自分の書いた処理を柔軟に使い回してみましょう!