为什么Ruby中的每个类都继承自Object,即使您不必指定该行为?
您会期待如下:
class Foo < Object; end
但
class Foo; end
就够了。 Ruby如何在内部做到这一点?
答案 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的内部结构 - 至少是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.