fr ja en ja zh ja ja ja en ja ja ja ja ja ja ja ja ja ja ja ja ja ja ja ja ja en ja ja ja ja en ja ja ja ja ja en ceb ja ja ja ja en ja en en ja en ja en ja en en ja en ja pt en ja en ja hbs_lat ja en ja es ja ja en
クラスの継承リスト: Proc < Object < Kernel < BasicObject
Proc は ローカル変数のスコープを導入しないことを除いて名前のない関数のように使えます。ダイナミックローカル変数は Proc ローカルの変数として使えます。
手続きオブジェクトを中断して、呼出し元(呼び出しブロックでは yield、それ以外では Proc#call) へジャンプし値を返すには next を使います。break や return ではありません。
ブロック付きメソッドに対して Proc オブジェクトを `&' を指定して渡すと呼び出しブロックのように動作します。しかし、厳密には以下の違いがあります。これらは、Proc オブジェクトが呼び出しブロックとして振舞う際の制限です。
問題なし (1..5).each { break }
LocalJumpError が発生します。 pr = Proc.new { break } (1..5).each(&pr)
lambda と proc と Proc.new とイテレータの違い
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 手続きオブジェクトを抜ける 手続きオブジェクトを抜ける 手続きオブジェクトを抜ける イテレータ メソッドを抜ける 手続きオブジェクトを抜ける 手続きオブジェクトを抜ける
orphan な手続きオブジェクトの挙動
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
new { ... } -> Proc
ブロックをコンテキストとともにオブジェクト化して返します。
self[*arg] -> ()
call(*arg) -> ()
self === *arg -> ()
yield(*arg) -> ()
手続きオブジェクトを実行してその結果を返します。
arity -> Integer
Proc オブジェクトが受け付ける引数の数を返します。
binding -> Binding
Proc オブジェクトが保持するコンテキストを Binding オブジェクトで返します。
curry -> Proc
curry(arity) -> Proc
Procをカリー化します
hash -> Integer
self のハッシュ値を返します。
to_s -> String
inspect -> 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? .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