【问题标题】:How to require file as part of a module in Ruby?如何在 Ruby 中将文件作为模块的一部分?
【发布时间】:2017-09-30 20:19:06
【问题描述】:

我有一个文件SomethingClass.rb,如下所示:

class SomethingClass
  def initialize
    puts "Hello World"
  end
end

我想require 文件SomethingClass.rb,并使SomethingClass 成为模块SomethingModule 的一部分无需更改文件。

另外,我想完全避免使 SomethingClass 成为该模块外部命名空间的一部分。换句话说,我想require 文件,我的应用程序的其余部分不应该改变,除了SomethingModule 将被定义。

这不起作用(我假设因为require 在Kernel 范围内执行):

module SomethingModule
  require './SomethingClass.rb'
end

这在 Ruby 中可行吗?

【问题讨论】:

  • 除非我误解了这个问题,否则这似乎与包含另一个文件中需要的类定义的文件没有任何关系。假设您有一个文件定义了一个类和一个模块(不是模块中的一个类)。我相信您希望在不更改类定义的情况下将类移动到模块内。那是对的吗?如果是这样,这就是问题的本质吗?
  • @CarySwoveland 是的,没错。我用require 提出了这个问题,因为这是我打算使用它的方式。我不确定使用require 是否可以使解决方案成为可能,而不是把一个类移到一个模块中。

标签: ruby module namespaces


【解决方案1】:

在不更改您的类文件的情况下,根据我收集到的信息,只有一些 hacky 方法可以做到这一点 - 请参阅 Load Ruby gem into a user-defined namespace 和 How to undefine class in Ruby?。

但是我认为如果你允许自己修改类文件,它会更容易一些。可能最简单的做法是将原始类名设置为肯定不会有名称冲突的名称,例如:

class PrivateSomethingClass
  def initialize
    puts "Hello World"
  end
end

module SomethingModule
  SomethingClass = PrivateSomethingClass
end

现在您在全局命名空间中定义了SomethingModule::SomethingClass,但没有定义SomethingClass。

另一种方法是使用工厂方法和anonymous class:

class SomethingClassFactory
  def self.build
    Class.new do
      def initialize
        "hello world"
      end
    end
  end
end

module SomethingModule
  SomethingClass = SomethingClassFactory.build
end

【讨论】:

    猜你喜欢
    • 2016-01-09
    • 2017-01-02
    • 2011-02-11
    • 1970-01-01
    • 2019-04-14
    • 1970-01-01
    • 2014-02-11
    • 2016-10-14
    • 2018-07-13
    相关资源
    最近更新 更多