Я динамически определяю имя модуля из аргумента, переданного в cli, например Required::Module::#{ARGV.first}
Есть ли способ проверить, существует ли этот модуль? Кроме того, как бы я запускал на нем методы, не зная его точное имя?
Я динамически определяю имя модуля из аргумента, переданного в cli, например Required::Module::#{ARGV.first}
Есть ли способ проверить, существует ли этот модуль? Кроме того, как бы я запускал на нем методы, не зная его точное имя?
Проверьте существование модуля с помощью метода const_get
:
begin
mod = Required::Module::const_get "ModuleName"
#It exists
rescue NameError
#Doesn't exist
end
Используйте const_defined?
для этого.
Required::Module.const_defined?(:ModuleName)
возвращает true или false.
defined?(Required::Module)
дает "constant"
, если он существует, и nil
, если это не так.
Обновление: Извините, не прочитал ваш вопрос правильно.
defined?(eval("Required::Module::"+string))
должен дать вам то, что вам нужно.
Вам нужно проверить:
Попробуйте следующее:
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)
Если вы получили ActiveSupport
mod = ("Required::Module::#{ARGV.first}".constantize rescue nil)
В случае, когда вы require
что-то, что расширяет что-то еще, вы не можете основывать свой тест на константе, потому что расширение не может определить новое. Вместо этого основывайте его на присутствии чего-то другого, как нового метода.
Я использую ниже, чтобы проверить, требуется ли open_uri_redirections:
if OpenURI.methods.include?(:redirectable_safe?)
# extension loaded
else
# extension not loaded
fi
Текущий выбранный ответ неверен. const_get
и const_defined
найдите любое имя константы, независимо от объекта, вызывающего этот метод. Например, если я хочу проверить MyModule::Rails
внутри приложения Rails, использование const_get
вернет нормальный модуль Rails.
Чтобы проверить константу в определенном пространстве имен, используйте метод constants
и проверьте свой класс:
MyModule.constants.include? ( "Rails" ) # = > false