On 10/10/05, Mathieu Bouchard <matju / artengine.ca> wrote:
> On Tue, 11 Oct 2005, TRANS wrote:
> > Ah, I see. So it's the same @x in either method --I thinking super would
> > behave the same as calling Q::H.x. Is this why super is "hard bound" at
> > compile time.
>
> What do you mean by hard-bound at compile time? In a super-call, the self
> of the callee is always the self of the caller. However the
> classes/modules involved are not necessarily predetermined:
>
>   module A; def foo; "A calls #{super}" end end
>   class B; def foo; "B" end end
>   class C; def foo; "C" end end
>   class D<B; include A; def foo; "D calls #{super}" end end
>   class E<C; include A; def foo; "E calls #{super}" end end
>   puts D.new.foo
>   puts E.new.foo
>
> displays:
>
>   D calls A calls B
>   E calls A calls C

Yes, in modules it's not so, but for classes it is.

  class A
    def x ; 10 ; end
  end
  => nil

  class B < A
    def x ; super + 100 ; end
  end
  => nil

  class C < B
    def x ; super + 1000 ; end
  end
  => nil

  class D < C
    def x ; super + 10000 ; end
  end
  => nil

  d = D.new
  => #<D:0xb7d57e04>

  d.x
  => 11110

  B.instance_method(:x).bind(d).call
  => 110

Despite the method being bound lower down the inheritance chain, it's
super is still bound to the origianl call higher up.

> But I don't know what that feature has to do with your problem though...

Cause this works:

  module Q
     module H
       def x ; @x ||= [] ; end
     end
     extend H
   end

   class R
     include Q
     extend Q::H
     def self.x ; @x ||= [] ; ancestors[1].x + @x  ; end
     def self.x! ; @x ||= [] ; end
   end

Which I was mistakingly thinking that's what super would do.

T.