gpt4 book ai didi

ruby - 使用双冒号时,为什么 Ruby 不将父模块添加到词法范围以进行常量查找?

转载 作者:行者123 更新时间:2023-12-03 00:11:41 25 4
gpt4 key购买 nike

这个问题是 this 的延伸问题。答案帮助我理解发生了什么,但我仍然质疑为什么。

在模块中定义两个类时,有两种编写方法。

使用模块 block :

module Foo
class FirstClass
def meth
puts 'HELLO'
end
end

class SecondClass
def meth
FirstClass.new.meth
end
end
end

Foo::SecondClass.new.meth

使用双冒号:

module Foo; end

class Foo::FirstClass
def meth
puts 'HELLO'
end
end

class Foo::SecondClass
def meth
FirstClass.new.meth
end
end

Foo::SecondClass.new.meth

这两种方法都适用于类定义,但是使用双冒号时不能直接查找 FirstClass SecondClass里面不包括FirstClass或写Foo::FirstClass 。发生这种情况是因为 Foo不属于 SecondClass 的词法范围当它用双冒号定义时,可以使用 Module.nesting 来演示。

为什么是Foo没有用双冒号添加到词法范围中?在较低级别 Ruby 的上下文中 source code ,为什么ruby_cref仅指向 Foo::SecondClass而不是ruby_cref指向SecondClass然后指向 Foo

例如:

+---------+       +---------+
| nd_next | <-----+ nd_next | <----+ ruby_cref
| nd_clss | | nd_clss |
+----+----+ +----+----+
| |
| |
v v
Foo SecondClass

最佳答案

让我问你相反的问题:为什么它?

正如您在上一个问题中发现的那样,模块嵌套很重要。对于一个快速直观的示例,

module Foo
puts self # executing in Foo context
module Bar
puts self # executing in Foo::Bar context
end
end

只有模块(及其子类,例如 Class)可以执行此操作 - 通过嵌套更改执行上下文。

现在,来看您的示例。第一个片段实际上相当于:

module Foo
# executing in Foo namespace context
FirstClass = Class.new
meth1 = proc do puts "HELLO" end
FirstClass.define_method(:meth, meth1)
SecondClass = Class.new
meth2 = proc do FirstClass.new.meth end
SecondClass.define_method(:meth, meth2)
SecondClass.new.meth
end

这里,假设我们在 main 级别执行此操作,所有引用都相对于 ::Foo。当我们编写FirstClass时,它被理解为::Foo::FirstClass

第二个片段实际上相当于

# executing in top namespace context
Foo = Module.new
Foo::FirstClass = Class.new
meth1 = proc do puts "HELLO" end
Foo::FirstClass.define_method(:meth, meth1)
Foo::SecondClass = Class.new
meth2 = proc do FirstClass.new.meth end # ERROR
Foo::SecondClass.define_method(:meth, meth2)
Foo::SecondClass.new.meth

这样写,第二个示例不起作用的原因可能就很明显了。如果这是在 main 中执行的,那么我们定义的 Foo::FirstClass 就会被理解为 ::Foo::FirstClass。错误行中提到的 FirstClass 被理解为 ::FirstClass,它从未定义过。

关于ruby - 使用双冒号时,为什么 Ruby 不将父模块添加到词法范围以进行常量查找?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59295287/

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