Super in instance_eval

Issue #2402 has been updated by shugo (Shugo M.).

Category set to core

shugo (Shugo M.) wrote:

まつもとさん、この件どうしましょうか?

個人的にはinstance_evalの中でsuperを呼ぶのはかなり特殊なケースだと思うので、
TypeErrorでよいように思いますが。

まつもとさん、いかがでしょうか。

再度まとめると、以下のようにinstance_eval中でsuperを呼ぶと、superで
呼び出した先のクラス・モジュールとselfの整合性が取れなくなるため、
現状では、NotImplementedErrorが発生します。

class Bar < Foo
def foo
x = Object.new
x.instance_eval do
super
end
end
end

NotImplementedErrorなのは、将来1.8と同様に動くように実装するという意図だと
思いますが、次の点からこの場合はエラーでもよいのではないかと考えています。

  • 1.8とインタプリタの構造が異なるため、上記のコードを動くようにするには実装コストも
    実行コストもかかる。

    制御フレームを辿ってもとのselfを見つける修正を試みましたが、orphanなProcから

    superを呼んだ時などに問題がありました。

  • 現状エラーが発生するが、誰も困っていなさそう。

ただ、この場合はエラーになるのが仕様ということにするのであれば、NotImplementedErrorは
不適切なので、TypeError(selfと呼び出し先メソッドのクラスが不整合という意味)などの他の
例外を発生させるようにしてはどうでしょうか。


Bug #2402: super in instance_eval

Author: shugo (Shugo M.)
Status: Assigned
Priority: High
Assignee: matz (Yukihiro M.)
Category: core
Target version: 2.0.0
ruby -v: ruby 1.9.2dev (2009-11-24 trunk 25909) [i686-linux]

=begin
instance_evalのブロック内でsuperを呼ぶと、instance_evalで変更された
selfに対してsuperの呼び出しを行ってしまうようです。

defiant:build$ cat t.rb
class Foo
def foo
p self
end
end

class Bar < Foo
def foo
x = Object.new
x.instance_eval do
super
end
end
end

Bar.new.foo
defiant:build$ ./ruby-trunk.1124 -v t.rb
ruby 1.9.2dev (2009-11-24 trunk 25909) [i686-linux]
#Object:0x8590f6c

Foo#fooが呼ばれるのにselfがObjectという、ちょっとおかしなことになっています。
ちょっと自信がありませんが、一応パッチを添付します。
=end