我正在通过从命令行传递的参数动态定义一个模块名称,例如 Required::Module::#{ARGV.first}
有没有办法检查该模块是否存在?并且如果不知道确切的名称如何运行它的方法?
我正在通过从命令行传递的参数动态定义一个模块名称,例如 Required::Module::#{ARGV.first}
有没有办法检查该模块是否存在?并且如果不知道确切的名称如何运行它的方法?
使用const_defined?
来实现此功能。
Required::Module.const_defined?(:ModuleName)
返回 true 或 false。
Module.const_defined?(:Name)
它会返回 true 或 false。 - SunTechniquedefined?(Required::Module)
如果它存在,则返回"constant"
,否则返回nil
。
更新:抱歉,没有仔细阅读您的问题。
defined?(eval("Required::Module::"+string))
这应该能给你想要的东西。
defined?(“Parade :: Procedure ::#{procedure.capitalize}”)
返回“expression”,即使我调用的模块不存在。 - Andrei Serdeliuc ॐeval
,特别是当 string
是用户输入的值时。这可能会造成严重的损害。(更多信息请参见 https://dev59.com/KnRB5IYBdhLWcg3wZWfi) - Andrew K使用const_get
方法检查模块是否存在:
begin
mod = Required::Module::const_get "ModuleName"
#It exists
rescue NameError
#Doesn't exist
end
const_defined?
来替代。 - horseyguymod = Required::Module.const_defined?("ModuleName") ? Required::Module::const_get "ModuleName" : nil
的操作。 - Leo CorreaRequired::Module::ModuleName
- 两者都会抛出 NameError
。但是,如果只有在运行时才知道模块名称,则这很有用。 - Aram Kocharyan您需要检查以下内容:
尝试这样做:
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)
if OpenURI.methods.include?(:redirectable_safe?)
# extension loaded
else
# extension not loaded
fi
instance_methods
等,const_defined?
包括第二个参数true(默认情况下,会考虑继承)和false(仅搜索接收者)。我认为我更喜欢使用它,即使它是一个相当模糊的布尔属性,因为Ruby解释器有更优化的搜索方法,而不是通过constants
创建一个Ruby数组,并要求Ruby用include?
进行搜索。 - Andrew Hodgkinson如果存在,则获取该类:
dynamic_klass = "Required::Module::#{ARGV.first}".classify.safe_constantize
如果类中存在该方法,则调用它:
dynamic_klass.send("some_method") if dynamic_klass.present?