Я динамически определяю имя модуля из аргумента, переданного в 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