首页 > 解决方案 > Ruby 类名解析中的歧义

问题描述

我最近在 Rails 代码库中进行了一些代码重构,在其中我转换了一些定义类似这样的类的代码(省略了类主体):

foo/user_bar.rb

module Foo
  class UserBar; end
end

foo/sub_user_bar.rb

module Foo
  class SubUserBar < UserBar; end
end

...到:

foo/bar/user.rb

module Foo
  module Bar
    class User; end
  end
end

foo/bar/sub_user.rb

module Foo
  module Bar
    class SubUser < User; end
  end
end

User这引入了一个微妙的问题,因为已经存在一个名为(Rails 模型)的顶级类,并且SubUser是从该类派生的,而不是从User同一个模块中派生的。我猜这是因为 Rails 加载类的顺序是不可预测的......?

无论如何,我发现我可以通过这样声明SubUser类来消除歧义:

class SubUser < self::User

...这似乎可行,尽管我在适度的搜索中找不到任何示例。不过,它看起来确实有点奇怪。现在我担心我真的应该为模块中的每个类都这样做,以防万一引入了同名的顶级类。

我公司的代码库中有两种样式的模块内类声明:

class A::B::Foo; end

和:

module A; module B; class Foo; end; end; end

我一直更喜欢后一种方法,因为它允许在没有完全限定名称的情况下访问模块中的其他名称,但现在我发现使用它时可能存在陷阱。那么这里的最佳做法是什么?

或者 Ruby 和/或 Rails 是否提供了其他更简洁的方法来解决问题?

标签: ruby-on-railsruby

解决方案


通常,如果您指定完整的命名空间路径有歧义:

module Foo
  module Bar
    class SubUser < Foo::Bar::User; end
  end
end

这可能看起来很冗长,但它也是具体且明确的。

User你想在哪里引用你指定的文字顶层::User


推荐阅读