我在开发功能时遇到了这个问题。假设有以下代码:
case 1:
module Person
module Employee
class Officer
def self.print_class(obj)
obj.is_a? Employee
end
end
end
end
case 2:
class Person::Employee::Officer
def self.print_class(obj)
puts obj.is_a? Employee
end
end
class Employee < ActiveRecord::Base
end
emp = Employee.last
我们有模型 Employee 。现在
对于案例 1:
Person::Employee::Officer.print_class(emp) 给出“假”
对于案例 2:
Person::Employee::Officer.print_class(emp) 给出“真”
为什么会这样?
最佳答案
::
是范围解析运算符。不同于 class
和 module
关键字它不会重新打开模块并正确设置模块嵌套。
例如:
TEST = "I'm in the global scope"
module Foo
TEST = "I'm scoped to foo"
end
module Foo::Bar
def self.test
TEST
end
def self.nesting
Module.nesting
end
end
puts Foo::Bar.test # "I'm in the global scope"
puts Foo::Bar.nesting.inspect [Foo::Bar]
这是因为模块嵌套是在定义时按词法解析的。当你这样做 module Foo::Bar
该模块嵌套是全局范围 - 当您引用 TEST
时未解析为 Foo::TEST
自从 Foo
不在模块嵌套中。在你的情况下 2
Employee
解析为 ::Employee
不是 Person::Employee
.因此,您应该始终显式嵌套类和模块,因为它将设置正确的模块嵌套并避免这些非常意外的模块查找。
TEST = "I'm in the global scope"
module Foo
TEST = "I'm scoped to foo"
module Bar
def self.test
TEST
end
def self.nesting
Module.nesting
end
end
end
puts Foo::Bar.test # "I'm scoped to foo"
puts Foo::Bar.nesting.inspect [Foo::Bar, Foo]
关于ruby-on-rails - 当以不同的方式编写时,范围解析在 ruby 中的工作方式不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62934207/