为什么Ruby中的每个类都继承自Object?

时间:2015-01-29 21:54:10

标签: ruby

为什么Ruby中的每个类都继承自Object,即使您不必指定该行为?

您会期待如下:

class Foo < Object; end

class Foo; end

就够了。 Ruby如何在内部做到这一点?

3 个答案:

答案 0 :(得分:3)

Ruby如何在内部执行此操作的问题并不完全有意义,因为特定机制是故意未记录的,并且尽管语言规范保持不变,但可能会随后发布更改。此外,还有许多Ruby解释器,他们都可以以不同的方式实现这种行为。

对于MRI,如果查看Class.new的来源,您会看到如果没有参数,则将super设置为Object:

if (argc == 0) {
    super = rb_cObject;
}
来自C API的

rb_define_class的工作方式类似(通过将NULL传递给rb_define_class_id):

if (!super) super = rb_cObject;

我不知道哪个代码路径class Foo; end最终会占用,但它并不重要。

答案 1 :(得分:2)

在内部,当您定义这样的类时:

class Foo < Bar; end

Ruby(至少是MRI和Rubinius版本)调用C方法,非常类似于此:

rb_define_class( "Foo", parent_class );

其中parent_class设置为指向Bar(我不太了解从您指定的裸名称找到 Bar的C代码,但是这与你的问题无关。)

写作时

class Foo; end    

然后使用的parent_class的值是rb_cObject,它是在Ruby的核心中预定义的,并且此引用也附加到Object常量,因此它将找到如果指定class Foo < Object

,则为相同的Ruby值

最终,这只是一个标准的默认机制,与您在方法定义中实现的相同。它的定义方式与使用任何其他参数的默认值类似,只是用于表达它的语法不同;决定是使用默认值还是接受您选择的基类由Ruby解析器处理。

如果您想了解更多关于Ruby的内部结构 - 至少是MRI Ruby和Rubinius - 在这个级别,您可以从了解C本机扩展开始。 This PDF covers the basics very well。 MRI Ruby的内部结构实际上是一个很大且相当平坦的#34; C API,如果你只知道一点C相对容易编码.Rubinius有点不同,但仍然提供相同的API以与原生扩展兼容。

答案 2 :(得分:-1)

这是语言的设计,视频为ri Object

Object is the default root of all Ruby objects.  Object inherits from
BasicObject which allows creating alternate object hierarchies.  Methods on
object are available to all classes unless explicitly overridden.