Вопрос по ruby, metaclass – Руби метакласс путаница

13

Я понимаю, что все классы в ruby являются экземплярами метакласса Class. И это "регулярно" объекты являются экземплярами этих классов (экземплярами метакласса Class).

Но я продолжаю задаваться вопросом, я имею в виду, что классы являются корнем объектов, сами классы являются экземплярами класса (так называемый метакласс, потому что его экземпляры являются классами). Я видел в некоторых блогах некоторые переопределения методаnew, класса Class.

Таким образом, класс ведет себя как класс, но его экземпляры являются классами. Похоже, у нас есть круг, похоже, класс - это экземпляр самого себя.

Я явно упускаю суть. Каково происхождение класса Class?

Вот пример, который меня смущает:

class Class
  def new
    #something
  end
end

Но ключевое словоclass подразумевает экземпляр класса Class. Так как же это работает?

Смотрите такжеThe class/object paradox confusion. Andrew Marshall
Это все черепахи! Andrew Grimm
Class.class # => Class Flexoid

Ваш Ответ

4   ответа
29

Легко: это не так. Во всяком случае, не в Ruby.

Как и в большинстве других языков, есть некоторые основные сущности, которые просто должны существовать. Они падают с неба, материализуются из воздуха, волшебным образом появляются.

В Ruby некоторые из этих волшебных вещей:

Object doesn't have a superclass, but you cannot define a class with no superclass, the implicit direct superclass is always Object. [Note: there may be implementation-defined superclasses of Object, but eventually, there will be one which doesn't have a superclass.] Object is an instance of Class, which is a subclass of Object (which means that indirectly Object is an instance of Object itself) Class is a subclass of Module, which is an instance of Class Class is an instance of Class

Ничто из этого не может быть объяснено в Ruby.

BasicObject, Object, Module а такжеClass все должны возникать одновременно, потому что они имеют круговые зависимости.

То, что это отношение не может быть выражено в коде Ruby, не означает, что в спецификации языка Ruby нельзя сказать, что так и должно быть. Разработчик должен выяснить, как это сделать. В конце концов, реализация Ruby имеет уровень доступа к объектам, которых у вас, как у программиста, нет.

Например, реализация Ruby может сначала создатьBasicObject, устанавливая оба своиsuperclass указатель и егоclass указатель наnull.

Затем он создаетObject, установив егоsuperclass указатель наBasicObject И егоclass указатель наnull.

Далее это создаетModule, установив егоsuperclass указатель наObject И егоclass указатель наnull.

Наконец, это создаетClass, установив егоsuperclass указатель наModule И егоclass указатель наnull.

Теперь мы можем перезаписатьBasicObject&'S,Object&'S,ModuleиClass& APOS; sclass указатель, указывающий наClassи мы сделали.

Это легко сделать снаружи системы, это выглядит странно изнутри.

Однажды ониdo Существуют, однако, вполне возможно реализовать большую часть их поведения в простом Ruby. Вам нужны только очень скромные версии этих классов, благодаря открытым классам Ruby вы можете добавить любую недостающую функциональность позже.

В вашем примереclass Class не создает новый класс с именемClassоткрываетсяexisting учебный классClass, который был дан нам средой выполнения.

Таким образом, вполне возможно объяснить поведение по умолчаниюClass#new в простом рубине:

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

[Примечание: на самом деле,initialize является частным, поэтому вам нужно использоватьobj.send(:initialize, *args, &block) обойти ограничение доступа.]

КСТАТИ:Class#allocate это еще одна из тех волшебных вещей. Он размещает новый пустой объект в пространстве объектов Ruby, что невозможно сделать в Ruby. Так,Class#allocate это то, что должно быть обеспечено системой времени выполнения.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededBasicObjectError: User Rate Limit ExceedednilError: User Rate Limit ExceededObjectError: User Rate Limit ExceededBasicObject.
Error: User Rate Limit ExceededObjectError: User Rate Limit ExceededdirectError: User Rate Limit ExceedednilError: User Rate Limit ExceededeventuallyError: User Rate Limit ExceededObjectError: User Rate Limit ExceedednilError: User Rate Limit ExceededBasicObjectError: User Rate Limit ExceededNSObjectError: User Rate Limit Exceeded
Error: User Rate Limit ExceededObjectError: User Rate Limit ExceededBasicObject.
1

эта статья _why может помочь в понимании поведения. Вы можете найти еще более глубокое погружение в эту тему у Паоло Перротты.Метапрограммирование Ruby.

Error: User Rate Limit Exceeded
2

класс является примером сам по себе. Это подкласс модуля, который также является экземпляром класса, а модуль является подклассом объекта, который также является экземпляром класса. Это действительно довольно круглый & # x2014; но это часть основного языка, а не что-то в библиотеке. Сама среда выполнения Ruby не имеет тех же ограничений, что и вы, или я, когда мы пишем код на Ruby.

Я никогда не слышал слово "метакласс" Раньше говорили о классе, хотя. Он вообще не используется в Ruby, но когда это так, он обычно является синонимом к так называемому «одноэлементному классу объекта». это еще более запутанная тема, чем треугольник Object-Module-Class.

Error: User Rate Limit Exceeded Perello
2

ссылка на сайт. Это встроенная ссылка суперкласса от собственного класса корня доClass учебный класс. Это может быть выражено

BasicObject.singleton_class.superclass == Class

Ключ к пониманию.class карта видит эту карту как полученную из ссылок на собственный класс и суперкласс: для объектаx, x.class это первый класс в цепочке суперклассаxсобственный класс. Это может быть выражено

x.class == x.eigenclass.superclass(n)

гдеeigenclass является «концептуальным псевдонимом»; изsingleton_class (устойчив к проблемам с непосредственными ценностями),y.superclass(i) средстваiсуперклассy а такжеn наименьший такой, чтоx.eigenclass.superclass(n) это класс. Эквивалентно, собственные классы в цепочке суперклассовx.eigenclass пропущены (см.rb_class_real что также показывает, что в МРТ, дажеsuperclass ссылки реализованы косвенно & # x2013; они возникают при пропуске & quot;iclasses& Quot;). Это приводит к тому, чтоclass каждого класса (а также каждого собственного класса) постоянноClass учебный класс.

Изображение предоставленоэта диаграмма.

Путаница в метаклассе имеет 2 основных источника:

Smalltalk. The Smalltalk-80 object model contains conceptual inconsistencies that are rectified by the Ruby object model. In addition, Smalltalk literature uses dialectics in terminology, which unfortunately has not been sufficiently remedied in the Ruby literature.

The definition of metaclass. At present, the definition states that metaclasses are classes of classes. However, for so called "implicit metaclasses" (the case of Ruby and Smalltalk-80) a much more fitting definition would be that of meta-objects of classes.

Похожие вопросы