From: Arlen Cuss Date: 2008-04-19T14:20:46+09:00 Subject: Included in Kernel, yet won't show up in `C::ancestors'? ------=_Part_6494_30447884.1208582446240 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit Content-Disposition: inline Hi all, I'm fairly sure I'm a long way down the path of madness with this one. Please bare with me. I've been on this for some time now. I've been trying to work out the order in which items appear in "SomeClass::ancestors". I thought I had it before: [SomeClass, SomeClass'sIncludedModules..., SuperClass, SuperClass'sIncludedModules, SuperSuperClass, ...] I constructed a test case: $ ruby -e 'module M; end; module N; end; class A; include M; end; class B < A; include N; end; p B.ancestors' [B, N, A, M, Object, Kernel] This is the expected result! But then I wondered.. what if we included something in `M'? It shouldn't appear according to my theory here, since M is not included by SomeClass itself. But, sure enough, it does appear. (which makes sense!) The reason I presumed this is because if I include a module in Kernel, it won't appear in the list of any Class's ancestors, yet it will appear in Kernel's: $ ruby -e 'module A; end; module Kernel; include A; end; class C; end; p C.ancestors; p Kernel.ancestors' [C, Object, Kernel] [Kernel, A] This confused me slightly, since it goes directly against what we experience with this: $ ruby -e 'module A; end; module B; include A; end; class C; include B; end; class D < C; end; p D.ancestors' [D, C, B, A, Object, Kernel] .. that is, the modules included by a superclass's included module appearing in the ancestors list. In the previous example, Object (superclass of C) includes Kernel, and we don't see Kernel's included A. Here, C (superclass of D) includes B, yet we also see A. So, that proves that theory wrong. In frustation, and in trying to work this out, my test case became larger and larger.. I think this provides about all the useful data we could hope for: $ ruby -e 'module M; end; module N; end; module O; end; module P; end; module Q; end; module R; include Q; end; module M; include O; end; module Kernel; include P; end; class Object; include R; end; class A; include M; end; class B < A; include N; end; p B::ancestors' [B, N, A, M, O, Object, R, Q, Kernel] modules M, N, O, P, Q, R. M includes O Object includes R, R includes Q Kernel includes P class A includes M class B derives from A, includes N To start, [B, N, A ..] shows that the included items are first, followed by the superclass. [.. A, M, O, Object ..] continues to demonstrate this, and also tells us that included items also have *their* included items. [M's O] Object is A's superclass.. [.. Object, R, Q, Kernel ..] agrees with the above results, showing that Object's included R is there, and R's included Q, and the Object's included Kernel .. [.. Kernel] then ruins things little, since Kernel's included P never makes it. I have a feeling Kernel's already being included by something (or it deriving from something-or-other) -- I have no idea, really -- has something to do with this. What interests me also is that Kernel::ancestors in this test *does* return [Kernel, P]. This ended up being quite long and drawn out, and I hope this interested you, or that you may have some advice. Cheers, Arlen. ------=_Part_6494_30447884.1208582446240--