Log In  

Cart #require-0 | 2024-03-17 | Embed ▽ | License: CC4-BY-NC-SA
13

I wrote Lua require function based on the include function found in /system/lib/head.lua:791.

This function loads Lua modules similar to standard require found in Lua:

  • it loads the file
  • executes the file
  • returns the module returned by included file
  • caches the module, so next call to require will return already loaded module

How to use:

  • put the source code of require function in your main.lua:
function require(name)
   if _modules == nil then
        _modules={}
    end

    local already_imported = _modules[name]
    if already_imported ~= nil then
        return already_imported
    end

    local filename = fullpath(name..'.lua')
    local src = fetch(filename) 

    if (type(src) ~= "string") then 
        notify("could not include "..filename)
        stop()
        return
    end 

    -- https://www.lua.org/manual/5.4/manual.html#pdf-load
    -- chunk name (for error reporting), mode ("t" for text only -- no binary chunk loading), _ENV upvalue
    -- @ is a special character that tells debugger the string is a filename
    local func,err = load(src, "@"..filename, "t", _ENV)
    -- syntax error while loading
    if (not func) then 
        send_message(3, {event="report_error", content = "*syntax error"})
        send_message(3, {event="report_error", content = tostr(err)})

        stop()
        return
    end

    local module = func()
    _modules[name]=module

    return module
end
  • write modules, for example create file named module.lua:
M = {}

function M.func()
    print("inside module.func()")
end

return M
  • import modules:
local module = require('module') -- will load and execute module.lua
module.func()
P#143480 2024-03-17 11:21 ( Edited 2024-03-23 23:46)

Thanks for your sharing!

What about making it a yotta library so it can be easily installed?

P#145131 2024-03-30 16:13 ( Edited 2024-03-30 16:15)
1

thanks this was really helpful! here's my slightly refactored version that provides 'loadfile' as well. i also changed 'require' to provide the module name as an argument, the way regular lua does.

local _modules = {}

function loadfile (filename)
  local src = fetch(filename)

  if (type(src) ~= "string") then
    notify("could not include "..filename)
    stop()
    return
  end

  -- https://www.lua.org/manual/5.4/manual.html#pdf-load
  -- chunk name (for error reporting), mode ("t" for text only -- no binary chunk loading), _ENV upvalue
  -- @ is a special character that tells debugger the string is a filename
  local func,err = load(src, "@"..filename, "t", _ENV)
  -- syntax error while loading
  if (not func) then
    send_message(3, {event="report_error", content = "*syntax error"})
    send_message(3, {event="report_error", content = tostr(err)})

    stop()
    return
  end
  return func
end

function require(name)
  local already_imported = _modules[name]
  if already_imported ~= nil then
    return already_imported
  end

  local filename = fullpath(name:gsub ('%.', '/') ..'.lua')

  local func = loadfile (filename)

  local module = func(name)
  _modules[name]=module

  return module
end
P#146844 2024-04-17 21:49

[Please log in to post a comment]