How does Inheritance work in Ruby?

不羁岁月 提交于 2019-11-29 13:02:35

Eigenclass is a sneaky hidden one. You have successfully revealed it by opening class. But it does not exist in the ancestors of normal class. And since it is hidden, you cannot see it by sending ancestors method to a eigenclass itself. The inheritance tree is like the following:

B ---S-->  Dave   ---S---> Object  ---S---> BasicObject
|            |               |                  |
E            E               E                  E
|            |               |                  |
#B --S--> #Dave   ---S---> #Object ---S---> #BasicObject --S---> Class,,Object,BasicObject

S stands for superclass, while E for eigenclass.

BernardK

An object (and also a class which is an object, instance of Class) has a class field which points to its class. Creating a singleton class (eigenclass/metaclass) creates an anonymous class and changes this pointer to point to the anonymous class, whose class pointer will point to the original class. The class method does not display the anonymous class, only the original class. The same for mixins. A class has a superclass field. The method include creates an anonymous proxy, the superclass pointer is changed to point to the anonymous proxy class, and from there to the superclass. The method ancestors does not show the anonymous class, but the name of the included module. The superclass method does not display the anonymous proxy class, only the original superclass.

You can read this : Why are symbols in Ruby not thought of as a type of variable?

In a comment to this answer, there is a link to an interesting article on singleton class that can be found on a Devalot blog.

One needs some time to assimilate these inheritance chains. As a good picture is worth a long explanation, I recommend chapter 24 Metaprogramming in the Pickaxe http://pragprog.com/book/ruby3/programming-ruby-1-9 which has various pictures about all these chains.

By default, ancestors method doesn't show the metaclass:
and 1. How would the B.ancestors ... look like when the eigenclasses are also included?

ancestors concerns the superclass chain. The eigenclass does not belong to the superclass chain.

p Dave.metaclass.ancestors
=> [Class, Module, Object, Kernel, BasicObject]
However, I assume the real one would be something like:
=> ["eigenclass", Class, Module, Object, Kernel, BasicObject]

Correct.

You can simplify your Dave class :

class Dave
    def self.say_hello    # another way to create an eigenclass, if not created before
      puts "Hello"
    end
    def self.metaclass    # A way to show the hidden eigenclass
        class << self
            self
        end
    end
end

Dave.say_hello           # => Hello
Dave.new.class.say_hello # => Hello
p Dave.metaclass.instance_methods(false) # => [:say_hello, :metaclass]
p Dave.singleton_methods                 # => [:say_hello, :metaclass]

def self.metaclass is superfluous since Ruby 1.9.2, which has introduced Object#singleton_class.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!