lua-users home
lua-l archive

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


Hi,

Yes, it can be done like this, but like I said, I don't view the Lua
script part as a separate module (or the DLL if you reverse the roles
of DLL and script).  The script is really private to the DLL and both
communicate through private functions and tables that are unreachable
from outside of the module.

I had a similar problem in previous versions of LuaSocket. The
implementation of socket.select was messy in the sense that it was
composed of both C and Lua code, with Lua parts that used C parts and
vice-versa. I don't know exactly what is your scenario, but I now tend
to avoid this double-dependency. Having C code depend on Lua code tends
to complicate the setup, although it might simplify the implementation
itself.

Why worry about someone being able to load an internal module? If someone does that, it should be their problem, shouldn't it? Can't you simply not document it? This should make it obvious that a module is internal. I know this is not a solution to your problem,
it's just sort of denying it exists. Sometimes this is the best
solution, though. :)

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

I wouldn't have to worry if require simply passed the path as an
argument.  :-)  Look at it as a win-win situation since both your
approach and mine could be implemented easily.  Moreover, the changes
it would take to loader_C (or require) are minimal.

This is somewhat assymetric. One of the ideas of the packaging system, I
think, is that you can place the same function in the package.preload
table and everything should work fine. In that case, you would be in bad
shape.

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.

Don't you agree that it would be much nicer if we only need to use
"module" and not rely on return values?  Then it is simple: "module"
determines the package table, period.  If a) modules are not placed
in the globals automatically and b) return values of packages are
ignored, there'd be no way around using "module" to properly setup a
package.

I am not sure. The current scheme makes it work in 99% of the cases with
no setup. With one extra line for the other 1% you can get it to work.
Is this too bad?

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
work.

But that is exactly what I *don't* want to do.  I think the "module"
approach is nice and easy.  (If only it would would bind to the
required name instead of the module name.  Again, the changes to
"module" and "require" to support this binding are minimal.)  Here's
another example of possibly weird behaviour.  Suppose we implement two
packages "a" and "b" both adding to module "a", but without "b"
requiring "a".  Then

   local b = require "b"
   local a = require "a"

doesn't load package "a", while

   local a = require "a"
   local b = require "b"

does.  With a modified module function, both would work as expected.
Or should we compose a list of additional coding rules like

-  When in doubt, end your package with "return _M"
-  Before doing "module(name)" where <name> is not the package name,
you should also do "require(name)"

But here you are focusing on a cases that are not commonly needed,
are somewhat pathological, and for which there are cookbook solutions.

1) If two modules are recursive, invoke module() on yourself before requiring()
your mate. This is just like a forward declaration.

2) If you are invoking module with a name other than your own, BEWARE. This
means you probably are extending someone else. In that case, require()
whoever it is that you are extending (it only makes sense). Also,
because you are not exporting where you should, make sure you return
your namespace, i.e., the one you are borrowing from. Alternatively,
store your namespace into the loaded table where it belongs. Finally,
you might consider placing your extension module as a submodule of
whoever it is that you are extending, just to make things obvious,
regardless of whether you export symbols to your own namespace or to
that of your master.

You try very hard!  ;-)

I know. :) There has to be some inertia, otherwise this thing never
converges...  But if there is a solution to a problem that is simpler
than the work around, I am all for it.

Seriously though, I think my small
wish list does not conflict with the spirit of the require proposal
(and would take only minimal changes):

1)  "module" binds to the "require"-ed name, not to the module name.

And how is "module" supposed to know what was the required name? Maybe
some magic environment trick...

3)  Drop the support for package return values, they're just confusing

I don't like this idea. One might desire to write a package whose only
exported symbol is a function. Returning that function works and is
useful.

[]s,
Diego.