Ruby 1.9.2 リファレンスマニュアル > ライブラリ一覧 > 組み込みライブラリ > Procクラス

class 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 オブジェクトを `&' を指定して渡すと 呼び出しブロックのように動作します。 しかし、厳密には以下の違いがあります これらは、Proc オブジェクトが呼び出しブロックとして振舞う際の制限です。

# 問題なし
(1..5).each { break }

# LocalJumpError が発生します。
pr = Proc.new { break }
(1..5).each(&pr)

lambda と proc と Proc.new とイテレータの違い

Kernel.#lambdaProc.new はどちらも Proc クラスのインスタンス(手続きオブジェクト)を生成しますが、 生成された手続きオブジェクトはいくつかの場面で挙動が異なります。 lambda の生成する手続きオブジェクトのほうが よりメソッドに近い働きをするように設計されています。

Kernel.#proc は Proc.new と同じになります。 引数に & を付けることで手続きオブジェクト化したブロックは、Proc.new で生成されたそれと 同じにように振る舞います。

引数の扱い

lambda のほうがより厳密です。引数の数が違っていると(メソッドのように)エラーになります。 Proc.new は引数を多重代入に近い扱い方をします。

例:

b1 = Proc.new{|a,b,c|
  p a,b,c
}
b1.call(2, 4)
#=> 2
    4
    nil

b2 = lambda{|a,b,c|
  p a,b,c
}
b2.call(2, 4)
#=> wrong number of arguments (2 for 3) (ArgumentError)

メソッド呼び出し(super・ブロック付き・yield)/ブロックパラメータの挙動 も参照してください。

ジャンプ構文の挙動の違い

return と break は、lambda と Proc.new では挙動が異なります。 例えば return を行った場合、lambda では手続きオブジェクト自身を抜けますが、 Proc.new では手続きオブジェクトを囲むメソッドを抜けます。

例:

def foo
  f = Proc.new { return :foo }
  f.call
  return
end

def bar
  f = lambda { return :bar }
  f.call
  return
end

def h
  yield
end

def hoge
  h{ return :hoge }
  nil
end

p foo()  #=> :foo
p bar()  #=> nil
p hoge() #=> :hoge

以下の表は、手続きオブジェクトの実行を上の例と同じように、手続きオブジェクトが定義されたのと 同じメソッド内で行った場合の結果です。

               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 === obj -> ()

@see Proc#call

self[*arg] -> ()
call(*arg) -> ()

手続きオブジェクトを実行してその結果を返します。

arity -> Fixnum

Proc オブジェクトが受け付ける引数の数を返します。

binding -> Binding

Proc オブジェクトが保持するコンテキストを Binding オブジェクトで返します。

curry -> Proc
curry(arity) -> Proc

Procをカリー化します

lambda? -> bool
parameters -> [object]

Proc オブジェクトの引数の情報を返します。

source_location -> [String, Fixnum] | nil

returns the ruby source filename and line number containing this proc or nil if this proc was not defined in ruby (i.e. native)

to_proc -> self

self を返します。

to_s -> String

self の文字列表現を返します。

yield(*arg) -> ()

Proc#call と同じですが、引数の数のチェックを行いません。

継承したメソッド

! != == =~ __id__ __send__ _dump class clone dclone display enum_for eql? equal? extend freeze frozen? hash initialize initialize_copy inspect instance_eval instance_exec instance_of? instance_variable_defined? instance_variable_get instance_variable_set instance_variables is_a? marshal_dump marshal_load method method_missing methods must_be must_be_close_to must_be_empty must_be_instance_of must_be_kind_of must_be_nil must_be_same_as must_be_within_epsilon must_equal must_include must_match must_raise must_respond_to must_send must_throw nil? pretty_inspect pretty_print pretty_print_cycle pretty_print_inspect pretty_print_instance_variables private_methods protected_methods public_methods remove_instance_variable respond_to? respond_to_missing? singleton_class singleton_method_added singleton_method_removed singleton_method_undefined singleton_methods taint tainted? tap to_a to_ary to_hash to_int to_io to_regexp to_str to_yaml to_yaml_properties to_yaml_style trust untaint untrust untrusted? wont_be wont_be_close_to wont_be_empty wont_be_instance_of wont_be_kind_of wont_be_nil wont_be_same_as wont_be_within_epsilon wont_equal wont_include wont_match wont_respond_to