gpt4 book ai didi

ruby - 不断查找

转载 作者:数据小太阳 更新时间:2023-10-29 07:02:22 26 4
gpt4 key购买 nike

场景#1:

在下面的示例中,puts Post::User.foo 行打印 foo。换句话说,Post::User 返回一个全局的 User 常量。

class User
def self.foo
"foo"
end
end

class Post
puts Post::User.foo
end
# => warning: toplevel constant User referenced by Post::User
# => foo

场景#2:

第二个示例会引发错误,因为未找到常量。

module User
def self.foo
"foo"
end
end

module Post
puts Post::User.foo
end
# => uninitialized constant Post::User (NameError)

场景 #2 的结果更直观。为什么在场景 #1 中找到常量?如果在场景 #1 中返回 User 常量,为什么在场景 #2 中没有发生这种情况?在场景 #2 中,Post 是一个模块,因此在这种情况下,应该在 Object.ancestors 中搜索常量,它也应该返回 User常量,但这并没有发生。

最佳答案

该行为是由发生在模块内部而不是类中的查找引起的。 (您正在查找模块内部的模块和类内部的类这一事实是无关紧要的)。

module M
def self.foo; "moo" end
end

class C
def self.foo; "coo" end
end

class A
A::M.foo rescue puts $! # warning: toplevel constant M referenced by A::M
A::C.foo rescue puts $! # warning: toplevel constant M referenced by A::M
end

module B
B::M.foo rescue puts $! # error: uninitialized constant B::M
B::C.foo rescue puts $! # error: uninitialized constant B::C
end

如果你看一下 C 代码,它们都会调用 rb_const_get_0 exclude=true, recurse=true, visibility=true。

在 A::M 的情况下,查找:

tmp = A
tmp::M # (doesn't exist)
tmp = tmp.super # (tmp = Object)
tmp::M # (exists, but warns).

在 B::M 的情况下,这样查找:

tmp = B
tmp::M # (doesn't exist)
tmp = tmp.super # (modules have no super so lookup stops here)

因为 exclude 为真,所以跳过了模块跳转到 (tmp = Object) 的常见边缘情况。这意味着 B::M 的行为与 module B 不同;男; end,这可以说是 ruby​​ 中的不一致。

关于ruby - 不断查找,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29324535/

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