Поиск метода на диаграмме взаимосвязей Руби? - PullRequest
0 голосов
/ 16 декабря 2018

Может ли кто-нибудь объяснить связь между диаграммой взаимосвязей классов Ruby и способом поиска метода в реальном коде Ruby C?

Диаграмма взаимосвязей из https://ruby -doc.org / core-2.5.3 / Class.html :

                     +---------+             +-...
                     |         |             |
     BasicObject-----|-->(BasicObject)-------|-...
         ^           |         ^             |
         |           |         |             |
      Object---------|----->(Object)---------|-...
         ^           |         ^             |
         |           |         |             |
         +-------+   |         +--------+    |
         |       |   |         |        |    |
         |    Module-|---------|--->(Module)-|-...
         |       ^   |         |        ^    |
         |       |   |         |        |    |
         |     Class-|---------|---->(Class)-|-...
         |       ^   |         |        ^    |
         |       +---+         |        +----+
         |                     |
 obj--->OtherClass---------->(OtherClass)-----------...

и поиск в Ruby-коде, похоже, пересекает элемент super RClass как flat list here : псевдокод

while (!st_lookup(RCLASS(klass)->m_tbl, ...)) {
    klass = RCLASS(klass)->super;
    ...
}

Где на приведенной выше диаграмме внутренние RClass.super и RBasic.klass (структуры C) указатели-стрелки будут сопоставлено ?Какой путь выберет поиск метода на этой диаграмме?В частности, диаграмма, кажется, содержит циклы.Как это интерпретировать?Что означает ... в

obj--->OtherClass---------->(OtherClass)-----------...

(синглтон синглтона?), Как осуществляется доступ к синглтону синглтона в Ruby и как он моделируется в реализации C?

1 Ответ

0 голосов
/ 17 декабря 2018

Я немного покопался, и функция ancestor, похоже, пересекает член c-struct RClass.super, так же как и метод looup .Поэтому, когда я делаю

class OtherClass end
obj = OtherClass.new
obj.class.singleton_class.singleton_class.ancestors => 
[#<Class:#<Class:OtherClass>>, \
 #<Class:#<Class:Object>>, \
 #<Class:#<Class:BasicObject>>, \
 #<Class:Class>, \
 #<Class:Module>, \
 #<Class:Object>, \
 #<Class:BasicObject>, \
 Class, \
 Module, \
 Object, \
 Kernel, \
 BasicObject]

     BasicObject
          ^           +---------+                 +--------+
          |           |         |                 |        |
      Kernel          | #<Class:BasicObject>      | #<Class:#<Class:BasicObject>>
          ^           |         ^                 |        ^
          |           |         |                 |        |
       Object         |   #<Class:Object>         | #<Class:#<Class:Object>>
          ^           |         ^                 |        ^
          |           |         |                 |        |
          +-------+   |         +--------+        |        |
                  |   |                  |        |        |
               Module |           #<Class:Module> |        |
                  ^   |                  ^        |        |
                  |   |                  |        |        |
                Class |           #<Class:Class>  |        |
                  ^   |                  ^        |        |
                  +---+                  +--------+        |
                                                           |
obj--->OtherClass --->#<Class:OtherClass>--->#<Class:#<Class:OtherClass>>

, это означает, что вертикальные стрелки на диаграмме можно рассматривать как обход RClass.super c-членов.С другой стороны, горизонтальные стрелки должны быть связаны с RBasic.klass, однако код Ruby выглядит асимметричным.

             ...
              |
obj--->   OtherClass 

Когда создается класс-одиночка, первый RBasic.klass получитRClass.super нового синглтон-класса.

             ...                           ...
            Object                   #<Class:Object>
              ^                             ^
              |                             |                  
          OtherClass                        |
              ^                             |
              |                             |
obj--->#<Class:#OtherClass:0x...> ->#<Class:OtherClass> -+
                                                       ^-+

и переход на один шаг дальше синглтона синглтона выглядит следующим образом:

             ...                         ...                        ...
            Object                  #<Class:Object>          #Class<#<Class:Object>>
              ^                           ^                          ^
              |                           |                          |
          OtherClass                      |                          |
              ^                           |                          |
              |                           |                          |
obj-->#<Class:#OtherClass:0x...>-->#<Class:OtherClass>-->#<Class:#<Class:OtherClass>>-+
                                                                                    ^-+

Значение / использование одноэлементного классаПонятно, однако значение / использование метаклассов немного эзотерично.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...