Actions
Bug #11163
closedBinding from Method#to_proc.binding cause BUG
ruby -v:
2.3dev
Description
Method オブジェクトから、
to_proc で取り出した Proc オブジェクトから、
Binding を取り出したものを使って eval しようとすると、BUG になります。
class C
D = :D
def foo
a = b = c = 123
end
def inspect
"<C object>"
end
end
C.new.method(:foo).to_proc.binding.eval("p [a, b, c]")
これは、Method#to_proc したときに、環境をテキトーに弄っているため、不整合を起こすものです。
そもそも、上記の例では foo メソッドは実行されていないため、foo の中の環境が取れる、という変な幻想を与える Binding が取れてはいけないのではないかと思います。
というわけで、このような Binding は、どんなものであるべきでしょうか。レシーバは取れる、cref は同じ、ローカル変数は空、くらいがいいのかと思いますが、どうでしょうか。
解決策としては、現状の method_proc() で何かテキトーに弄っているところではなく、proc_binding で、特殊な環境を作るように変更する必要があるのではないかと思います。
Updated by ko1 (Koichi Sasada) about 10 years ago
- Status changed from Open to Closed
Applied in changeset r50592.
- proc.c: fix issues caused by binding created from Method#to_proc.
[Bug #11163] - vm.c (vm_cref_new_toplevel): export as rb_vm_cref_new_toplevel().
- test/ruby/test_method.rb: add some assersions.
Updated by ko1 (Koichi Sasada) about 10 years ago
とりあえず、この方針で作り直しました。
def ... で定義しているもの以外、例えば attr なんか由来の Method から binding 作ると、微妙に動かないものがあります。その辺はしょうがない、でも良いですかねえ。
Updated by nagachika (Tomoyuki Chikanaga) about 10 years ago
- Related to Bug #10432: wrong receiver of Binding from Method added
Updated by nagachika (Tomoyuki Chikanaga) about 10 years ago
- Backport changed from 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN to 2.0.0: REQUIRED, 2.1: REQUIRED, 2.2: REQUIRED
#10432 での修正(r48160)による regression ということですよね。 ruby_2_2 の HEAD でも再現しました。
r48160 は 2.0.0, 2.1 にも backport 済みなので Backport 欄を REQUIRED にしておきます。
Actions
Like0
Like0Like0Like0Like0