如何检查 Lua 中是不是存在模块?

Posted

技术标签:

【中文标题】如何检查 Lua 中是不是存在模块?【英文标题】:How to check if a module exists in Lua?如何检查 Lua 中是否存在模块? 【发布时间】:2013-03-03 23:31:51 【问题描述】:

我正在使用包含 GNOME 菜单的 xdg-menu-to-awesome-wm 到 generate a Lua file,用于 Awesome WM 中的 inclusion。由于可能没有安装生成器脚本,我需要一些方法让 Lua 只使用 require menu 模块如果它存在

我不想查看文件名,因为它可能位于package.path 中的任何位置。一种选择是忽略模块不存在时创建的异常,但我宁愿不忽略任何 other 异常 - 我确实想知道模块是否包含任何语法或其他错误。不幸的是,reference 没有指定可以生成哪些异常,所以我不知道该怎么做。

【问题讨论】:

今天刚遇到这个问题,对于答案部分中有多少人似乎没有意识到未找到模块与存在但存在语法错误的模块不同,这有点令人震惊,或者(更糟糕的是)需要它们自己的模块,这些模块本身不存在或有语法错误。 finnw 的回答正是我所需要的 【参考方案1】:

看,'luafilesystem' 模块也有同样的问题,我是这样解决的,

local haslfs,lfs = pcall(require,"lfs")
if haslfs then
  configLines["PROJECT_HOME"] = lfs.currentdir()
else
  configLines["PROJECT_HOME"] = prompt("Project path > ")
end

'lfs' 这里是模块句柄。并且 pcall 用于在不传播错误的情况下知道模块是否真正加载。

【讨论】:

【参考方案2】:

我所做的是将 require 包装在 pcall 中,以便加载模块并捕获加载失败。有一个完整的功能,我可以在这里从我们的服务器下载和安装缺少的模块: http://www.fhug.org.uk/wiki/doku.php?id=plugins:code_snippets:module_require_with_load

function loadrequire(module)
    local function requiref(module)
        require(module)
    end
    res = pcall(requiref,module)
    if not(res) then
        -- Do Stuff when no module
    end
end
loadrequire('menu')

【讨论】:

看起来不错;很快就会尝试。 Nit:只是我,还是缩进不一致? 当你可以做res = pcall(require, module)时,你为什么要创建一个本地内部函数? 10b0 - 主要是因为我输入了一些并粘贴了其余部分。 Mike 老实说我不记得了,我想我是从一些插件的几个地方调用它的。 这不会传播语法错误 - 只是一个布尔结果,没有指示出了什么问题 - 所以它实际上不是我需要的。 @DreamEater 这不是我问的。这只是一个非常常见的可读性因素。【参考方案3】:

如果需要区分缺失模块和语法错误,可以直接访问package.searchers中的搜索器功能。

这些函数将:

如果成功则返回加载函数 如果找不到模块,则返回一个字符串 如果存在语法错误则抛出错误

所以你可以做的是模仿require 搜索模块的方式,依次调用每个搜索器,直到其中一个返回函数。与require 不同,如果找不到模块,即如果每个搜索器函数都返回一个字符串,我们不需要抛出错误。

function isModuleAvailable(name)
  if package.loaded[name] then
    return true
  else
    for _, searcher in ipairs(package.searchers or package.loaders) do
      local loader = searcher(name)
      if type(loader) == 'function' then
        package.preload[name] = loader
        return true
      end
    end
    return false
  end
end

【讨论】:

if isModuleAvailable("menu") then require("menu") end 的测试结果:如果menu 包含语法错误则崩溃,如果它缺失或正确则成功。谢谢!

以上是关于如何检查 Lua 中是不是存在模块?的主要内容,如果未能解决你的问题,请参考以下文章

检查目录是不是存在于lua中?

如何使用 lua 检查 Roblox 中是不是存在对象?

Lua - 检查数组是不是存在

如何编写一个函数来检查模块列表是不是存在,否则在 Python 中安装模块

如何检查单元和功能是不是存在?

如何检查表是不是包含Lua中的元素?