[ruby-dev:46851] [ruby-trunk - Bug #2402] super in instance_eval

From: "shugo (Shugo Maeda)" <redmine@...>
Date: 2013-01-09 08:24:49 UTC
List: ruby-dev #46851
Issue #2402 has been updated by shugo (Shugo Maeda).

Category set to core

shugo (Shugo Maeda) 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
https://bugs.ruby-lang.org/issues/2402#change-35300

Author: shugo (Shugo Maeda)
Status: Assigned
Priority: High
Assignee: matz (Yukihiro Matsumoto)
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



-- 
http://bugs.ruby-lang.org/

In This Thread

Prev Next