Bug #2402
super in instance_eval
| Status: | Assigned | Start date: | 11/25/2009 | |
|---|---|---|---|---|
| Priority: | Normal | Due date: | ||
| Assignee: | % Done: | 0% |
||
| Category: | - | |||
| Target version: | 2.0.0 | |||
| ruby -v: | ruby 1.9.2dev (2009-11-24 trunk 25909) [i686-linux] |
Description
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という、ちょっとおかしなことになっています。
ちょっと自信がありませんが、一応パッチを添付します。
Related issues
Associated revisions
* insns.def (invokesuper): check consistency between class of self and
class of method being invoked by super. This is temporary measure
for YARV. See [ruby-core:30313] in detail. See [ruby-dev:40959]
[ruby-dev:39772] [ruby-core:27000] [ruby-core:27230]
* vm_insnhelper.c (vm_search_superclass): ditto.
History
Updated by shugo (Shugo Maeda) over 2 years ago
特異クラス定義でsuperした時はNoMethodErrorになるようです。
defiant:build$ cat t2.rb
class Foo
def foo
p self
end
end
class Bar < Foo
def foo
x = Object.new
class << x
super
end
end
end
Bar.new.foo
defiant:build$ ./ruby-trunk.1124 -v t2.rb
ruby 1.9.2dev (2009-11-24 trunk 25909) [i686-linux]
t2.rb:11:in `singletonclass': super called outside of method (NoMethodError)
from t2.rb:10:in `foo'
from t2.rb:16:in `<main>'
1.8ではFoo#fooが呼ばれます。
defiant:build$ ruby-1_8 -v t2.rb
ruby 1.8.8dev (2009-10-22 revision 25430) [i686-linux]
#<Bar:0xb7ea443c>
参考までに他の処理系では以下のような挙動でした。
defiant:build$ ir -v t2.rb
IronRuby 0.9.1.0 on .NET 2.0.0.0
#<Bar:0x0000056>
defiant:build$ jruby -v t2.rb
jruby 1.5.0.dev (ruby 1.8.7 patchlevel 174) (2009-11-12 421150b) (Java HotSpot(TM) Client VM 1.6.0_16) [i386-java]
#<Class:#<Object:0x180cf2a>>
defiant:build$ rbx -v t2.rb
rubinius 0.13.0-dev (1.8.7 e614007b 2009-11-06) [i686-pc-linux-gnu]
An exception occurred running t2.rb
No method 'bytecode' on an instance of NilClass. (NoMethodError)
それぞれ個性があって面白いですね。
個人的には例外でもいいんじゃないかなと思いますが、1.9のinstance_evalでの
superや、JRubyの特異クラス定義でのsuperのように、変なレシーバでsuperが
呼ばれてしまうのはまずいんじゃないかと思います。
Updated by ujihisa (ujihisa .) over 2 years ago
- Status changed from Open to Assigned
- Assignee set to matz (Yukihiro Matsumoto)
Updated by mame (Yusuke Endoh) about 2 years ago
- Assignee changed from matz (Yukihiro Matsumoto) to ko1 (Koichi Sasada)
遠藤です。
> instance_evalのブロック内でsuperを呼ぶと、instance_evalで変更された
> selfに対してsuperの呼び出しを行ってしまうようです。
再現しました。以下で SEGV することも確認しました。
class MyArray < Array
def reverse
"foo".instance_eval do
super
end
end
end
MyArray.new([1,2,3]).reverse
パッチも見ました。速度劣化は気になりますが、正しいと思います。
vm_search_superclass を追ってみたところ、recv が必要になるのは、
現在のコンテキストが include された module に所属するメソッドの
場合 (ICLASS) だけのようですので、その時まで recv の同定を遅延
させると、速度劣化も気にならなくなるかもと思います。
ただ、その辺の修正は [ruby-dev:40959] の修正の後にやったほうが
いい予感がするので、最適化は後にして、とりあえずこの問題は前田
さんのパッチで close するのがいいと思います。
--
Yusuke Endoh <mame@tsg.ne.jp>
Updated by ko1 (Koichi Sasada) about 2 years ago
パッチは全然見てないのですが,遠藤さんが良いと仰ってるので良いのではないかと思います.
Updated by mame (Yusuke Endoh) almost 2 years ago
- Target version set to 2.0.0
遠藤です。 [Bug #2502] [Bug #3136] あたりで super の修正は後回しにしようということに なり、r28043 でとりあえずの対策をしたので、1.9.x にします。 -- Yusuke Endoh <mame@tsg.ne.jp>
Updated by nahi (Hiroshi Nakamura) 11 months ago
- Target version changed from 2.0.0 to 1.9.3
Updated by ko1 (Koichi Sasada) 11 months ago
- Target version changed from 1.9.3 to 2.0.0
すみません,1.9.4 送りで....