Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 729bf78

Browse files
committed
fix a bug in defined?(super) which returns the incorrect value if use in included module
Test Code: ---- module Stuff def foo puts "In Stuff#foo" if defined?(super) puts "Calling super" super else puts "No super" end end end module OtherStuff def foo puts "In OtherStuff#foo" p defined?(super) end end class NoSuper include Stuff end NoSuper.new.foo class WithSuper include OtherStuff include Stuff end WithSuper.new.foo Result ---- $ macruby t.rb In Stuff#foo Calling super /Volumes/Mac/Users/watson/tmp/t.rb:6:in `foo': super: no superclass method `foo' for #<NoSuper:0x4001a33a0> (NoMethodError) from /Volumes/Mac/Users/watson/tmp/t.rb:23:in `<main>' Expected ---- $ ruby t.rb In Stuff#foo No super In Stuff#foo Calling super In OtherStuff#foo nil
1 parent e0f5b81 commit 729bf78

File tree

1 file changed

+19
-4
lines changed

1 file changed

+19
-4
lines changed

vm.cpp

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1687,16 +1687,31 @@ rb_vm_defined(VALUE self, int type, VALUE what, VALUE what2, rb_vm_outer_t *oute
16871687
case DEFINED_SUPER:
16881688
case DEFINED_METHOD:
16891689
{
1690-
VALUE klass = CLASS_OF(self);
1691-
if (type == DEFINED_SUPER) {
1692-
klass = RCLASS_SUPER(klass);
1693-
}
16941690
if (what == 0) {
16951691
rb_raise(rb_eRuntimeError,
16961692
"defined?(super) out of a method block isn't supported");
16971693
}
1694+
1695+
VALUE klass = CLASS_OF(self);
16981696
const char *idname = rb_id2name((ID)what);
16991697
SEL sel = sel_registerName(idname);
1698+
if (type == DEFINED_SUPER) {
1699+
Class current_super_class = GET_VM()->get_current_super_class();
1700+
if (current_super_class) {
1701+
klass = (VALUE)current_super_class;
1702+
sel = GET_VM()->get_current_super_sel();
1703+
}
1704+
else {
1705+
klass = RCLASS_SUPER(klass);
1706+
}
1707+
VALUE ary = rb_attr_get(klass, idIncludedModules);
1708+
if (ary != Qnil) {
1709+
int count = RARRAY_LEN(ary);
1710+
for (int i = 0; i < count; i++) {
1711+
klass = RCLASS_SUPER(klass);
1712+
}
1713+
}
1714+
}
17001715

17011716
bool ok = class_getInstanceMethod((Class)klass, sel) != NULL;
17021717
if (!ok && idname[strlen(idname) - 1] != ':') {

0 commit comments

Comments
 (0)