在Ruby的相互关系图中查找方法?

时间:2018-12-16 14:49:45

标签: ruby class methods

有人可以解释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代码中的查找似乎遍历RClass的super成员作为 flat 列表here:伪代码

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

在上图中的内部RClass.superRBasic.klass(C结构)  指针箭头是否被映射?在此图中,方法查找将采用哪条路径?特别是该图似乎包含循环。如何解释?

中的...是什么
obj--->OtherClass---------->(OtherClass)-----------...

均值(单例的单例?),如何在Ruby中访问单例的单例,以及如何在C实现中对其建模?

1 个答案:

答案 0 :(得分:1)

我进行了一些挖掘,ancestor函数似乎遍历RClass.super c结构成员,与method 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>>-+
                                                                                    ^-+

单例类的含义/用法是可以理解的,但是元类的含义/用法有些深奥。