l0b0
l0b0

Reputation: 58988

How to check if a module exists in Lua?

I'm using xdg-menu-to-awesome-wm to generate a Lua file containing the GNOME menu, for inclusion in Awesome WM. Since the generator script may not be installed, I need some way for Lua to only require the menu module if it exists.

I don't want to go looking through file names, since it could be anywhere in package.path. One option would be to ignore the exception created when the module does not exist, but I'd rather not ignore any other exceptions - I do want to know if the module contains any syntax or other errors. The reference unfortunately doesn't specify which exceptions can be generated, so I'm not sure how to do it.

Upvotes: 10

Views: 15351

Answers (4)

vitiral
vitiral

Reputation: 9248

I created a simple want function for optional imports.

-- Optional require. Example:                                             
--     myMod, err = want'myMod'                                           
--     if not myMod then print(err) end                                   
local function want(name)                                                 
  local out; if xpcall(                         
      function()  out = require(name) end,           
      function(e) out = e end)
  then return out          -- success                                     
  else return nil, out end -- error                                       
end  

LICENSE: This code is in the public domain

Upvotes: 0

KRoy
KRoy

Reputation: 1406

Look, I had the same problem with 'luafilesystem' module, I worked it out like this,

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

'lfs' here is the module handle . And pcall is used to know if the module is really loaded without propagating the error.

Upvotes: 10

Jane T
Jane T

Reputation: 2091

What I do is wrap the require in a pcall so that the module is loaded and a fail to load can be caught. There is a fully worked function which I use to download and install the missing modules from our servers here: 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')

Upvotes: 6

finnw
finnw

Reputation: 48659

If you need to distinguish between a missing module and a syntax error, you can directly access the searcher functions in package.searchers.

These functions will:

  • Return a loader function if successful
  • Return a string if the module is not found
  • Throw an error if there is a syntax error

So what you can do is mimic the way require searches for a module, calling each searcher in turn until one of them returns a function. Unlike require, we need not throw an error if the module is not found, i.e. if every searcher function returns a string.

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

Upvotes: 19

Related Questions