lua-users home
lua-l archive

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


1.  For developing extension modules in C we apply a scheme where part
of the module is in C (let's say a DLL, but could also be statically
linked) and another part is in an accompanying Lua script.  So we have
basically two files (DLL, Lua) per module.  Under the current proposal
it is not possible to cleanly deploy such a module:

The way I do it is to have the Lua script load the C module and add to
it all the sugar that it chooses too. In the next distribution of
LuaSocket, I have socket/core.dll and socket/socket.lua. Require"socket"
invokes socket/socket.lua, which requires socket.core and then adds
stuff to it. Both invoke module("socket") so that goodies end up in the
main namespace.

It is not worth it to worry about paths. I would suggest you simply use
the engine provided by require itself.

2.  I find it odd that the call <module(modname)> stores its table (if it
didn't exist already) in package.loaded[modname], since this name is not
necessarily "require"-ed anywhere.  Suppose we do <require(name)> and
this leads to a <module(modname)> call.  Then I'd expect that module
would store the table at package.loaded[name] (i.e. the inner-most
required name).  As an example, suppose we develop a package "complex"
but decide to see it as an extension of "math".  Then the complex
package could look something like:
   module "math"

   function complex(re, im)
     -- return a complex number

   I = complex(0, 1)

   -- etc. etc.
+    return _M

Under the current implementation, <require "complex"> would simply
return true instead of the math table.  The other scheme *does* need
some rule to enforce that a <module(modname)> call consistently
returns the same table.  We could use the globals (_G) for that or
something like a package.modules table.  (Or, better still, a table
that is private to the "module" function, since "require" is the
public interface to load a package/module.)

All you have to do is return _M in the end of your module definition (as
I added above). In C, you only have to return 1 from your loader, because
luaL_module already leaves the namespace table on the stack.

3.  I use the opposite order in calling "require" and "module", so
instead of

   local aap = require "aap"
   module "noot"

I use

   module "noot"
   local aap = require "aap"

because it handles possible cyclic dependencies better (aap could
simply be "true" instead of the aap package table in the first snippet
above).  Are there any unexpected (=unwanted) consequences?

It doesn't seem to cause any harm. Except I have been rooting for
module() to clear out the globals altogether. In that case you would
have to write

     local require = require
     module "noot"
     local app = require"app"

Recursion detection, I believe, was meant to prevent infinite loops, not
guarantee that loops would be resolved correctly.

In fact, inverting the order, in the case you choose to implement your modules by simply filling up a table and returning it, would still not

It only works because module() places the namespae in _LOADED[name].

Thanks for your comments! How did I go?