假设我在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自动加载尝试使用当前类name
加载Bar,在单例类中为nil
,默认为“Object”。
klass_name = name.presence || "Object" # from active_support/dependencies.rb
这会导致Rails从“app / models / bar.rb”而不是“app / models / foo / bar.rb”加载Bar
。
如果我使用Qux.something
定义def self.something
,则.name
为“Foo :: Qux”而不是nil,并且自动加载功能正常。
我现在看到3个选项可以解决这个问题:
1)重命名Bar
个班级之一
2)到处使用self.
语法
3)命名空间Bar
,Foo::Bar
明确无处不在
我不喜欢这些选项,因为:
1)Bar
只是最适合的名称
2)class << self
本身完全没问题并被大多数红宝石开发者使用,所以下一个可怜的家伙很快再次遇到同样问题的机会很高
3)与2)相同,它并没有真正解决潜在的“问题”,并且有人将在未来浪费一些时间来弄清楚为什么他的代码不能按预期工作。
你能想到还有另一种更好的选择吗?