In Ruby, a class is an object. Okay. Then this class should have a class that this class has created.

It turns out that this class - Class

 class Viktor end puts Viktor.class.name # => "Class" 

But then the most interesting

 puts Class.class.name # => "Class" irb(main):020:0> Class === Class.class => true irb(main):021:0> Class === Class.class.class => true 

Those. a class, like an object, is created by itself.

Please explain to me the nature of this phenomenon. Is he singlton?

    1 answer 1

    I found in SO an answer to a similar question. I will give here a free translation.


    As with most other languages, there are some basic instances in Ruby, the existence of which is originally embedded in the language. They descended from heaven, materialized from thin matters, were born in a magical way.

    Here is a list of these magical things:

    • Object has no superclass, but you cannot define an object without a superclass, the direct superclass (though not always explicitly) is Object . [Note: the superclass for Object can be set, but in the end, there will always be an object that does not have a superclass.]
    • Object is an instance of Class , which is a subclass of Object (which means, Object indirectly an instance of Object itself)
    • Class is a Module subclass that is an instance of Class
    • Class is an instance of Class

    None of these things can be explained in Ruby.

    BasicObject , Object , Module and Class - they all have to be created at the same time, because they have a cyclical dependency on each other.

    The fact that such dependencies cannot be explained in the Ruby language does not mean that the specifications of the Ruby language cannot say that this should be so. This is the task of the performer: to figure out how to do this. In the end, the Ruby Executive has access to objects that the programmer simply does not have.

    For example, a Ruby executor can start by creating BasicObject by setting its superclass and class pointers to null .

    Then create an Object , setting superclass equal to BasicObject and class equal to null .

    Then create a Module , setting superclass to Object and class to null .

    Finally, create a Class , setting its superclass to Module and class to null .

    Now reassign the pointers to Class for BasicObject Object, Module, и Class to равными class`.

    All this is quite easy to do from the outside, but it is difficult to imagine how to implement it from the inside.

    Once they began to exist, it is perfectly possible to implement most of their functionality in pure Ruby. You only need to have a bare skeleton of these classes, because thanks to the open Ruby classes, we can complement their functionality at any time.

    Execution class Class does not create a new class named Class , but opens an already existing class Class , which has already been provided to us by the runtime.

    So it's quite simple to present the standard behavior of Class#new in pure Ruby:

     class Class def new(*args, &block) obj = allocate # another magic thing that cannot be explained in Ruby obj.initialize(*args, &block) return obj end end 

    [Note: in fact, initialize is a private method, so you need to use obj.send(:initialize, *args, &block) to bypass access restrictions.]

    By the way, Class#allocate is another magic trick. It allocates a new empty object in the Ruby object space, which cannot be done by Ruby itself. So Class#allocate is something that should also be provided by the runtime.


    From myself I will add that in the source code of RubyMine ( rubystubs23/class.rb ) you can find a commentary that explains everything quite profitably:

     # Classes, modules, and objects are interrelated. In the diagram # that follows, the vertical arrows represent inheritance, and the # parentheses metaclasses. All metaclasses are instances # of the class `Class'. # +---------+ +-... # | | | # BasicObject-----|-->(BasicObject)-------|-... # ^ | ^ | # | | | | # Object---------|----->(Object)---------|-... # ^ | ^ | # | | | | # +-------+ | +--------+ | # | | | | | | # | Module-|---------|--->(Module)-|-... # | ^ | | ^ | # | | | | | | # | Class-|---------|---->(Class)-|-... # | ^ | | ^ | # | +---+ | +----+ # | | # obj--->OtherClass---------->(OtherClass)-----------... 

    Approximate translation of the comment above the diagram:

    Classes, objects and modules are interrelated. In the diagram below, vertical arrows mean inheritance, and parentheses - metaclass. All metaclasses are instances of class Class .