From: ara.t.howard@... Date: 2007-01-25T00:48:56+09:00 Subject: Re: Trickery in the ancestors chain On Wed, 24 Jan 2007, Paolo Nusco Perrotta wrote: > Try this: > > module M > def hello; p 'M'; end > end > > class C > def hello; p 'C'; end > end > > class D < C; end > > class C; include M; end > class D; include M; end > D.ancestors -> [D, C, M, Object, Kernel] > D.new.hello -> "C" > > > Now restart from a clean slate and change the last few lines: > > class D; include M; end > class C; include M; end > D.ancestors -> [D, M, C, M, Object, Kernel] > D.new.hello -> "M" > > > Ruby silently prevents you from including a module that has been > included by an ancestor. Why? > why do you say that? you first tell D to include M, which ruby does. then you tell C to include M, which ruby does. that's why M is in the ancestors list twice. am i missing something. try working with this from the console so we're on the same page: harp:~ > cat a.rb # # take one # module M def hello; 'M'; end end class C def hello; 'C'; end end class D < C; end class C; include M; end class D; include M; end p D.ancestors #=> [D, C, M, Object, Kernel] p D.new.hello #=> "C" # # take two # Object.instance_eval{ remove_const 'C' remove_const 'D' } class C def hello; 'C'; end end class D < C; end class D; include M; end p D.ancestors #=> [D, M, C, Object, Kernel] class C; include M; end p D.ancestors #=> [D, M, C, M, Object, Kernel] p D.new.hello #=> "M" harp:~ > ruby a.rb [D, C, M, Object, Kernel] "C" [D, M, C, Object, Kernel] [D, M, C, M, Object, Kernel] "M" this makes perfect sense to me attm - you're picking up 'hello' from M and it's first up the method lookup chain. but maybe i'm not understanding? regards. -a -- we can deny everything, except that we have the possibility of being better. simply reflect on that. - the dalai lama