Ruby 2.5.0 リファレンスマニュアル > ライブラリ一覧 > 組み込みライブラリ > Procクラス
クラス・モジュールの継承リスト: Proc < Object < Kernel < BasicObject
ブロックをコンテキスト(ローカル変数のスコープやスタックフレーム)とともにオブジェクト化した手続きオブジェクトです。
Proc は ローカル変数のスコープを導入しないことを除いて名前のない関数のように使えます。ダイナミックローカル変数は Proc ローカルの変数として使えます。
Proc がローカル変数のスコープを保持していることは以下の例で変数 var を参照できていることからわかります。
例
var = 1
$foo = Proc.new { var }
var = 2
def foo
$foo.call
end
p foo # => 2
手続きオブジェクトを中断して、呼出し元(呼び出しブロックでは yield、それ以外では Proc#call) へジャンプし値を返すには next を使います。break や return ではありません。
例
def foo
f = Proc.new{
next 1
2 # この行に到達することはない
}
end
p foo().call #=> 1
ブロック付きメソッドに対して Proc オブジェクトを `&` を指定して渡すと呼び出しブロックのように動作します。しかし、厳密には以下の違いがあります。これらは、Proc オブジェクトが呼び出しブロックとして振舞う際の制限です。
問題なし
(1..5).each { break }
LocalJumpError が発生します。
pr = Proc.new { break }
(1..5).each(&pr)
Kernel.#lambda と Proc.new はどちらも Proc クラスのインスタンス(手続きオブジェクト)を生成しますが、生成された手続きオブジェクトはいくつかの場面で挙動が異なります。 lambda の生成する手続きオブジェクトのほうがよりメソッドに近い働きをするように設計されています。
Kernel.#proc は Proc.new と同じになります。引数に & を付けることで手続きオブジェクト化したブロックは、Proc.new で生成されたそれと同じように振る舞います。
lambda のほうがより厳密です。引数の数が違っていると(メソッドのように)エラーになります。 Proc.new は引数を多重代入に近い扱い方をします。
Proc.new は引数の数が違っていてもエラーにならない
b = Proc.new{|a,b,c|
p a,b,c
}
b.call(2, 4)
#=> 2
4
nil
lambda は引数の数が違うとエラーになる
b = lambda{|a,b,c|
p a,b,c
}
b.call(2, 4)
# => wrong number of arguments (given 2, expected 3)
メソッド呼び出し(super・ブロック付き・yield)/ブロックパラメータの挙動 も参照してください。
return と break は、lambda と Proc.new では挙動が異なります。例えば return を行った場合、lambda では手続きオブジェクト自身を抜けますが、 Proc.new では手続きオブジェクトを囲むメソッドを抜けます。
例
def test_proc
f = Proc.new { return :from_proc }
f.call
return :from_method
end
def test_lambda
f = lambda { return :from_lambda }
f.call
return :from_method
end
def test_block
tap { return :from_block }
return :from_method
end
p test_proc() #=> :from_proc
p test_lambda() #=> :from_method
p test_block() #=> :from_block
以下の表は、手続きオブジェクトの実行を上の例と同じように、手続きオブジェクトが定義されたのと同じメソッド内で行った場合の結果です。
return next break Proc.new メソッドを抜ける 手続きオブジェクトを抜ける 例外が発生する proc メソッドを抜ける 手続きオブジェクトを抜ける 例外が発生する lambda 手続きオブジェクトを抜ける 手続きオブジェクトを抜ける 手続きオブジェクトを抜ける イテレータ メソッドを抜ける 手続きオブジェクトを抜ける 手続きオブジェクトを抜ける
Proc を生成したメソッドから脱出した後、手続きオブジェクトからの return, break は例外 LocalJumpError を発生させます。ただし、上でも説明した通り lambda で生成した手続きオブジェクトはメソッドと同じように振る舞うことを意図されているため、例外 LocalJumpError は発生しません。
例
def foo
Proc.new { return }
end
foo.call
# => in `call': return from proc-closure (LocalJumpError)
以下の表は、手続きオブジェクトの実行を上の例と同じように、手続きオブジェクトが定義されたメソッドを脱出してから行った場合の結果です。
return next break Proc.new 例外が発生する 手続きオブジェクトを抜ける 例外が発生する proc 例外が発生する 手続きオブジェクトを抜ける 例外が発生する lambda 手続きオブジェクトを抜ける 手続きオブジェクトを抜ける 手続きオブジェクトを抜ける
定義 | 説明 | |
---|---|---|
new -> Proc
|
ブロックをコンテキストとともにオブジェクト化して返します。 |
定義 | 説明 | |
---|---|---|
self[*arg] -> ()
|
手続きオブジェクトを実行してその結果を返します。 |
|
arity -> Integer
|
Proc オブジェクトが受け付ける引数の数を返します。 |
|
binding -> Binding
|
Proc オブジェクトが保持するコンテキストを Binding オブジェクトで返します。 |
|
curry -> Proc
|
Procをカリー化します |
|
hash -> Integer
|
self のハッシュ値を返します。 |
|
to_s -> String
|
self の文字列表現を返します。 |
|
lambda? -> bool
|
手続きオブジェクトの引数の取扱が厳密であるならば true を返します。 |
|
parameters -> [object]
|
Proc オブジェクトの引数の情報を返します。 |
|
source_location -> [String, Integer] | nil
|
ソースコードのファイル名と行番号を配列で返します。 |
|
to_proc -> self
|
self を返します。 |
!
!=
__id__
__send__
instance_eval
instance_exec
method_missing
singleton_method_added
singleton_method_removed
singleton_method_undefined
!~
<=>
==
=~
_dump
class
clone
define_singleton_method
display
enum_for
eql?
equal?
extend
freeze
frozen?
initialize
initialize_copy
instance_of?
instance_variable_defined?
instance_variable_get
instance_variable_set
instance_variables
is_a?
itself
marshal_dump
marshal_load
method
methods
nil?
object_id
pretty_inspect
pretty_print
pretty_print_cycle
pretty_print_inspect
pretty_print_instance_variables
private_methods
protected_methods
psych_to_yaml
public_method
public_methods
public_send
remove_instance_variable
respond_to?
respond_to_missing?
send
singleton_class
singleton_method
singleton_methods
taint
tainted?
tap
to_a
to_ary
to_hash
to_int
to_io
to_regexp
to_str
trust
untaint
untrust
untrusted?
yield_self
.yaml_tag
::ARGF
::ARGV
::DATA
::ENV
::FALSE
::NIL
::RUBY_COPYRIGHT
::RUBY_DESCRIPTION
::RUBY_ENGINE
::RUBY_ENGINE_VERSION
::RUBY_PATCHLEVEL
::RUBY_PLATFORM
::RUBY_RELEASE_DATE
::RUBY_REVISION
::RUBY_VERSION
::SCRIPT_LINES__
::STDERR
::STDIN
::STDOUT
::TOPLEVEL_BINDING
::TRUE