QA@IT

Ruby の Kernel.#eval の第二引数に Proc オブジェクトを渡すことはできますか

2458 PV

リファレンスマニュアル にはできると書いてある気がしますが、なかなかうまくできません。

eval('', Proc.new {}) # TypeError: wrong argument type Proc (expected Binding)

自分が何か勘違いをしている気もするので、ご教示願います。

ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-darwin11.3.0] を使用しています。

回答

リファレンスマニュアルの記述が 1.8 のものになっていると思います。1.9 では Binding 以外とれなくなっているようです。

1.9.3 のコードを見る限り、Binding オブジェクト以外が来たときは、TypeError が投げられます。

vm_eval.c にある関数 eval_string_with_cref が eval の行きつく先で、scope に eval 第二引数がわたってきます。997 行目で、rb_obj_is_kind_of(scope, rb_cBinding) して、Binding クラスかどうか確認しています。

一方、1.8.7ではeval.cの関数evalで処理されます。6529 行目で rb_obj_is_proc(scope) が true のもののみ処理されるようになっています。6520 行目のエラーメッセージより、Proc or Binding が scope として期待されているのがわかります。

編集 履歴 (2)
  • るりま側にバグのチケットをだしておきました http://bugs.ruby-lang.org/issues/6599 -
  • ありがとうございます。1.9.3 で Binding オブジェクト以外が来たときは warning ではなく例外が出ているようですが、違うケースがあるのでしょうか -
  • 回答が間違ってますね。rb_raise() で TypeError をあげていますね。修正しときます。 -
ウォッチ

この質問への回答やコメントをメールでお知らせします。