gpt4 book ai didi

ruby - 是什么阻止我在 Ruby 中包含一个类?

转载 作者:行者123 更新时间:2023-12-01 10:17:39 25 4
gpt4 key购买 nike

我正在尝试了解一些 Ruby 内部结构:

尝试包含而不是模块,导致TypeError:(这是设计使然)

class C
end

class Foo
end

Foo.include(C)
#=> TypeError: wrong argument type Class (expected Module)

我想知道类型检查是如何“在幕后”工作的。

因为类 模块,我假设 Ruby 检查参数是否是 Module 的实际实例:

C.is_a?(Module)        #=> true
C.instance_of?(Module) #=> false

听起来很合理,不是吗?

但是当我定义自己的 Module 子类并创建该子类的实例时,它工作得很好:

class Klass < Module
end

K = Klass.new

Foo.include(K)
# no error

但是KKlass的实例,就像CClass的实例一样。而KlassModule的子类,就像Class一样:

K.is_a?(Module)        #=> true
K.instance_of?(Module) #=> false

K.class #=> Klass
C.class #=> Class

Klass.superclass #=> Module
Class.superclass #=> Module

那么 include 中的类型检查实际上做了什么?

是否存在允许 Ruby 区分模块和类的隐藏属性?

因为这是特定于实现的:我对 YARV/MRI 特别感兴趣。

最佳答案

正如@Stefan 评论的那样,Module#include 调用宏Check_Type(module, T_MODULE)。您可以在 https://ruby-doc.org/core-2.6/Module.html#method-i-include 中找到它

进一步挖掘源码,可以发现在头文件ruby.h中,有一行

#define Check_Type(v,t) rb_check_type((VALUE)(v),(t))

所以Check_Type只是rb_check_type的一个方便的别名,你可以在error.c<中找到rb_check_type的定义/strong>:

void
rb_check_type(VALUE x, int t)
{
int xt;

if (x == Qundef) {
rb_bug(UNDEF_LEAKED);
}

xt = TYPE(x);
if (xt != t || (xt == T_DATA && RTYPEDDATA_P(x))) {
unexpected_type(x, xt, t);
}
}

int t 是类型的唯一“ID”,int xtx 的实际类型的 ID。您可以看到 if (xt != t || ...),因此 Check_Type 正在检查类型等价性,而不是 is-a 关系。

长话短说

Ruby 检查包含的模块是否实际上是一个模块而不是一个类。

关于ruby - 是什么阻止我在 Ruby 中包含一个类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59766403/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com