假设我在 Rails 应用程序的不同模块(全局命名空间/无命名空间和“Foo”)中有两个同名的类(“Bar”)。这两个类分别位于“app/models/bar.rb”或“app/models/foo/bar.rb”中,因此由rails自动加载。
# "app/models/foo/bar.rb"
module Foo
class Bar
def self.some_method
end
end
end
# "app/models/bar.rb"
class Bar
end
我在 Foo 命名空间中有另一个类,它在类方法中使用 Bar 类。
module Foo
class Qux
class << self
def something
Bar.some_method # This raises a NoMethod error because
# it uses the Bar defined in the global namespace
# and not the one in Foo
end
end
end
end
Rails 自动加载尝试使用单例类中的当前类加载 Bar name
,nil
默认为“Object”。
klass_name = name.presence || "Object" # from active_support/dependencies.rb
这会导致 RailsBar
从“app/models/bar.rb”而不是“app/models/foo/bar.rb”加载。如果我Qux.something
用def self.something
then定义.name
是 "Foo::Qux" 而不是 nil 并且自动加载正常工作。
我目前看到 3 个选项可以解决此问题:
1)重命名其中一个Bar
类
2)在self.
任何地方都使用语法
3)在任何地方Bar
都Foo::Bar
显式地 命名空间
我不喜欢这些选项中的任何一个,因为:
1)Bar
只是最适合的名称
2)class << self
本身非常好,并且被大多数 ruby 开发人员使用,所以下一个可怜的人很快就会再次遇到同样的问题的可能性很高
3) 与 2) 相同,它没有并没有真正解决潜在的“问题”,将来有人会浪费一些时间来弄清楚为什么他的代码不能按预期工作。
您能想到其他更好的选择吗?