Namespaces And Modules

lua-users home
wiki

[!] VersionNotice: The below article pertains to an older Lua version, Lua 4. Lua 5.1 has a module system, environments, etc.

Lua does not have namespaces. It is sometimes nice to organise your code into packages and modules with namespaces to avoid name clashes and to organise your code. Here are some suggestions for providing support in Lua.

There is a Lua technical note which dicusses modules and packages [1].

Executing Lua files in a namespace

Question: Could the dofile command could be expanded to dofile(filename, table) and the table passed used as the global table for executing the file? e.g.,
String = {}
dofile("stringlib.lua",String)
x = String.strlen("a string")
(lhf) How about this:
function dofile(f,t)
  local globals=globals
  local g=globals(t)
  local rc=%dofile(f)
  globals(g)
  return rc
end

"Global" keyword

Currently (in Lua versions 4.0 and less) no support exists for a "global" keyword currently. Lua 4.1 and onwards may support this feature (details in mailing list archives). This could be simulated as follows:

(lhf) If you're willing to use a "global" declaration, then something very similar can be done right now: Instead of a "global" keyword, use a "global" function, with the syntax:

global "myvar" -- one name only
or
global{"a","b"} -- several names
Here is the "global" function:
do
  local G={}
  function global(x)
    if type(x)=="string" then
      %G[x]=1
    else
      for i,v in x do
        %G[v]=1
      end
    end
  end
end

You can now implement the semantics you want by setting tag methods for "setglobal" and/or "getglobal" that checks the name against G.

Thus to implement the need-declaration-to-write-to-globals semantics, set the "setglobal" tag method and raise an error if the given variable is not in G. The error will be show as soon as it happens; ie no sleeper!

For details, see the FAQ on uninitialized and read-only variables.

The problem with this approach is that declarations last for ever, not only for the current block.

(ET) Or the simple way:

global = globals()
...
global.x = 1
print(global.y)


See also: SampleCode , ClassesAndMethods
RecentChanges · preferences
edit · history
Last edited January 5, 2007 5:43 am GMT (diff)