なかだです。

moduleのメソッド内で、defined?(super)と実際にsuperが呼べるかが
食い違うことがあるようです。

  module M1
    def foo
      "OK"
    end
  end
  module M2
    def foo
      [defined?(super), super]
    end
  end
  class C
    include M1
    include M2
  end
  p C.new.foo	# => [nil, "OK"]

* eval.c (is_defined): inheritance line adjustment as like as
  rb_call_super().

Index: eval.c =================================================================== RCS file: /cvs/ruby/src/ruby/eval.c,v retrieving revision 1.539 diff -u -2 -p -r1.539 eval.c --- eval.c 24 Sep 2003 23:56:11 -0000 1.539 +++ eval.c 25 Sep 2003 07:59:05 -0000 @@ -1988,5 +1988,17 @@ arg_defined(self, node, buf, type) return type; } - + +static VALUE +last_class(self, klass) + VALUE self, klass; +{ + VALUE k = CLASS_OF(self); + + while (k && !(BUILTIN_TYPE(k) == T_ICLASS && RBASIC(k)->klass == klass)) { + k = RCLASS(k)->super; + } + return k; +} + static char* is_defined(self, node, buf) @@ -2005,6 +2017,10 @@ is_defined(self, node, buf) if (ruby_frame->orig_func == 0) return 0; else if (ruby_frame->last_class == 0) return 0; - else if (rb_method_boundp(RCLASS(ruby_frame->last_class)->super, - ruby_frame->orig_func, 0)) { + val = ruby_frame->last_class; + if (BUILTIN_TYPE(val) == T_MODULE) { + val = last_class(self, val); + if (!val) return 0; + } + if (rb_method_boundp(RCLASS(val)->super, ruby_frame->orig_func, 0)) { if (nd_type(node) == NODE_SUPER) { return arg_defined(self, node->nd_args, buf, "super"); @@ -5237,12 +5253,9 @@ rb_call_super(argc, argv) klass = ruby_frame->last_class; if (BUILTIN_TYPE(klass) == T_MODULE) { - k = CLASS_OF(self); - while (!(BUILTIN_TYPE(k) == T_ICLASS && RBASIC(k)->klass == klass)) { - k = RCLASS(k)->super; - if (!k) { - rb_raise(rb_eTypeError, "%s is not included in %s", - rb_class2name(klass), - rb_class2name(CLASS_OF(self))); - } + k = last_class(self, klass); + if (!k) { + rb_raise(rb_eTypeError, "%s is not included in %s", + rb_class2name(klass), + rb_class2name(CLASS_OF(self))); } if (RCLASS(k)->super == 0) {
-- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦