1

假设我在 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 namenil默认为“Object”。

klass_name = name.presence || "Object"  # from active_support/dependencies.rb

这会导致 RailsBar从“app/models/bar.rb”而不是“app/models/foo/bar.rb”加载。如果我Qux.somethingdef self.somethingthen定义.name是 "Foo::Qux" 而不是 nil 并且自动加载正常工作。

我目前看到 3 个选项可以解决此问题:

1)重命名其中一个Bar
2)在self.任何地方都使用语法
3)在任何地方BarFoo::Bar显式地 命名空间

我不喜欢这些选项中的任何一个,因为:

1)Bar只是最适合的名称
2)class << self本身非常好,并且被大多数 ruby​​ 开发人员使用,所以下一个可怜的人很快就会再次遇到同样的问题的可能性很高
3) 与 2) 相同,它没有并没有真正解决潜在的“问题”,将来有人会浪费一些时间来弄清楚为什么他的代码不能按预期工作。

您能想到其他更好的选择吗?

4

0 回答 0