ruby-on-rails - Ruby 类名称解析中的歧义

标签 ruby-on-rails 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

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

  • 不要在 module 中声明类;始终使用完全限定名称 ( class A::B::C::Foo < A::B::C::Bar )
  • module 中声明类但始终完全限定父类(super class)名称 ( module A; module B; module C; class Foo < A::B::C::Bar )
  • module 中声明类并使用不合格的名称,但始终使用 self::在同一模块中扩展类时
  • module 中声明类并使用非限定名称,但要注意顶级 namespace 中可能发生的名称冲突(似乎有风险)

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

最佳答案

通常在有歧义的地方指定完整的命名空间路径:

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

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

在您想要引用文字顶级 User 的地方,您需要指定 ::User

关于ruby-on-rails - Ruby 类名称解析中的歧义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54260744/

相关文章:

ruby-on-rails - Redis 中带有前缀的元素的统计信息

ruby-on-rails - rails : methods from module included in controller not available in view

ruby - 简单的 Ruby 变量可变性

用于跨平台桌面应用程序的 Ruby?

ruby - Ruby 或 Perl 有没有好的流程监控框架?

ruby-on-rails - 仅显示 act_as_taggable_on 标签云中最流行的标签

javascript - $(document).ready 中的元素在某种情况下未定义

ruby-on-rails - 在没有任何错误消息的情况下在 Heroku 上调试 500 错误

ruby-on-rails - 如何加密必须传输的 PIN?

ruby - 从 Ruby block 中提取 AST