Reputation: 19328
The Ruby documentation has a simple definition for the Module#ancestors method that talks about what ancestors returns when it's called on modules, but does not say anything about when ancestors is called on classes.
Returns a list of modules included in mod (including mod itself).
I'm trying to decipher the purpose of the ancestors method when it's called on classes, especially singleton class object. Here's an example:
module InstanceMethods; end
module ClassMethods; end
class A; end
class B < A
include InstanceMethods
extend ClassMethods
end
B.ancestors # => [B, InstanceMethods, A, Object, Kernel, BasicObject]
B.singleton_class.ancestors # => [ClassMethods, Class, Module, Object, Kernel, BasicObject]
Questions:
Why is the receiver not included in the ancestors list when the method is called on singleton_class objects? I would have expected B.singleton_class.ancestors
to equal [B, ClassMethods, Class, Module, Object, Kernel, BasicObject]
I think the ancestor path for B's singleton class should be more like this (this isn't perfect because it shouldn't be using the singleton class of modules):
B.singleton_class.ancestors.map(&:singleton_class) # => [#<Class:ClassMethods>, #<Class:Class>, #<Class:Module>, #<Class:Object>, #<Class:Kernel>, #<Class:BasicObject>]
I typically use ancestors view the inheritance chain and get a better idea of Ruby's method lookup. Perhaps the method is not well suited for this task. What task is the ancestors method well suited for?
Upvotes: 1
Views: 706
Reputation: 2796
I think you'll really like the ruby 2.1
then!
$ rbenv local 2.1.0
roman.brodetski@nb-rbrodetski []
$ irb
...
irb(main):008:0> B.singleton_class.ancestors
=> [#<Class:B>, ClassMethods, #<Class:A>, #<Class:Object>, #<Class:BasicObject>, Class, Module, Object, Kernel, BasicObject]
irb(main):009:0>
I also think it's a great thing that your mind is synchronized with the language developers!
Here is the redmine issue: https://bugs.ruby-lang.org/issues/8035
Upvotes: 3