lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Here's a proposed module implementing 4.1's require() for 4.0.  It should be
mostly compatible, although it won't refresh its internal path on change to
LUA_PATH.

Intended use:

    local require = require or dofile
    require "xmlrpc.lua"

and just give the absolute path to require.lua on the command line:

    lua ~/require.lua -f xmlclient.lua

In fact, building a script or alias for this might be a good idea.  One
alternative for bootstrapping is for your top level scripts to start:

    dofile(LUA_REQUIRE or getenv("LUA_REQUIRE") or "")

and then specify LUA_REQUIRE someplace in the environment.

Note that this module adds path-searching to dofile() as well; many existing
modules specify their requirements with dofile.

BTW, my first glance at the 4.1 LUA_PATH made it look like trailing slashes
are mandatory in path elements; is this really the right thing for
user-friendliness and compatibility?

Jay

-- dofile(LUA_REQUIRE or getenv"LUA_REQUIRE" or "")

-- Suggested use:
--
-- bin/lua ~/require.lua -f yourfilename.lua
--
-- local require=require or dofile
-- require "xmlrpc.lua"

if require then return end
rawdofile = rawdofile or dofile

local Public, Private = {},{}
Require = Public

Private.default_path = {n=3; "", "/usr/local/share/lua-4.0/",
"/usr/share/lua-4.0/"}

if getenv("HOME") then
  tinsert(Private.default_path, getenv("HOME").."/share/lua-4.0/")
end

function Private.init_path()
  if LUA_PATH or getenv("LUA_PATH") then
    local l_path = {n=0}
    local s = LUA_PATH or getenv("LUA_PATH")
    gsub(s, "([^;]+)", function (seg) tinsert(%l_path, seg) end)
    %Public.path = l_path
  else
    %Public.path = %Private.default_path
  end
end

Private.init_path()

Private.loaded = {}

function Private.dofile_on_path(package, path)
  for i = 1,getn(path) do
    local prefix = path[i]
    local file = prefix..package
    local r = rawdofile(file)
    if r then return r end
  end
  return nil
end

function Public.require(package)
  if %Private.loaded[package] then return end
  if %Private.dofile_on_path(package, %Public.path) then
    %Private.loaded[package]=1
  else
    error("required package not found: "..package)
  end
end

function Public.dofile(file)
  local r = rawdofile(file)
  if r then return r end
  return %Private.dofile_on_path(file, %Public.path)
end

require = Public.require

-- Delete this if all the modules you care about use require.
dofile = Public.dofile