Как запросить файл как часть модуля в Ruby?

У меня есть файл 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?

1 ответ

Без изменения вашего файла класса, из того, что я собрал, есть только несколько хакерских способов сделать это - см. Загрузка гема Ruby в пользовательское пространство имен и Как отменить определение класса в Ruby?,

Однако я думаю, что если вы позволите себе изменить файл класса, это будет немного проще. Вероятно, самое простое, что можно сделать, это установить исходное имя класса в такое, которое, несомненно, не будет иметь конфликта имен, например:

class PrivateSomethingClass
  def initialize
    puts "Hello World"
  end
end

module SomethingModule
  SomethingClass = PrivateSomethingClass
end

Теперь у вас есть SomethingModule::SomethingClass определяется, но не SomethingClass в глобальном пространстве имен.

Другой способ сделать это - использовать фабричный метод и анонимный класс:

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

module SomethingModule
  SomethingClass = SomethingClassFactory.build
end
Другие вопросы по тегам