Подтвердить что ты не робот

Проверьте, существует ли модуль в рубине

Я динамически определяю имя модуля из аргумента, переданного в cli, например Required::Module::#{ARGV.first}

Есть ли способ проверить, существует ли этот модуль? Кроме того, как бы я запускал на нем методы, не зная его точное имя?

4b9b3361

Ответ 1

Проверьте существование модуля с помощью метода const_get:

begin
    mod = Required::Module::const_get "ModuleName"
    #It exists
rescue NameError
    #Doesn't exist
end

Ответ 2

Используйте const_defined? для этого.

Required::Module.const_defined?(:ModuleName)

возвращает true или false.

Ответ 3

defined?(Required::Module)

дает "constant", если он существует, и nil, если это не так.

Обновление: Извините, не прочитал ваш вопрос правильно.

defined?(eval("Required::Module::"+string))

должен дать вам то, что вам нужно.

Ответ 4

Вам нужно проверить:

  • существует константа, относящаяся к модулю,
  • объект, к которому константа содержит ссылку, является модулем.

Попробуйте следующее:

 def module_exists?(name, base = self.class)
   base.const_defined?(name) && base.const_get(name).instance_of?(::Module)
 end

Затем в вашем коде:

 module_exists?(ARGV.first, Required::Module)

Он вернет true, если в заданном пространстве пространства имен есть модуль данного имени. Разница между примерами, приведенными в других ответах, заключается в том, что он вернет false, если запрашиваемое имя относится к классу, а не к модулю.

Включить классы в тест

Если вы хотите изменить это поведение и заставить метод также возвращать true для классов (а не только модулей), измените instance_of? на is_a?.

Способ ООП

Вы также можете кодировать его более объектно-ориентированным способом, если ваш модуль Required::Module является единственным модулем, который вы тестируете для подмодулей:

 module Required::Module
   def submodule_exists?(name)
     const_defined?(name) && const_get(name).instance_of?(::Module)
   end
 end
 module_function :submodule_exists?

Затем в вашем коде:

 Required::Module.submodule_exists?(ARGV.first)

Ответ 5

Если вы получили ActiveSupport

mod = ("Required::Module::#{ARGV.first}".constantize rescue nil)

Ответ 6

В случае, когда вы require что-то, что расширяет что-то еще, вы не можете основывать свой тест на константе, потому что расширение не может определить новое. Вместо этого основывайте его на присутствии чего-то другого, как нового метода.

Я использую ниже, чтобы проверить, требуется ли open_uri_redirections:

if OpenURI.methods.include?(:redirectable_safe?)
  # extension loaded
else
  # extension not loaded
fi

Ответ 7

Текущий выбранный ответ неверен. const_get и const_defined найдите любое имя константы, независимо от объекта, вызывающего этот метод. Например, если я хочу проверить MyModule::Rails внутри приложения Rails, использование const_get вернет нормальный модуль Rails.

Чтобы проверить константу в определенном пространстве имен, используйте метод constants и проверьте свой класс:

MyModule.constants.include? ( "Rails" ) # = > false