[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: More about packaging (hopefully not too long)
- From: RLake@...
- Date: Tue, 8 Jun 2004 07:06:39 +0100
Diego Nehab escribió:
> Whatever we do, I prefer that each library creates its own table.
> Having the library receive a table to fill doesn't seem to be so
> advantageous. Besides, libraries written in Lua would require deeper
> modifications.
The advantage is that the library can be imported
into another module
before it has been created. If you have two libraries
which refer to
each other, and you don't want to put them into the
"global" namespace
(which might not exist in any meaningful sense anyway),
then there is
really no other way of doing it that I can see.
I don't see any deep modifications here. I have some
chunk which
looks like this:
local module = {}
function module:foo() ... end
function module:bar() ... end
return module
I change it to this:
return function(module)
function module:foo() ... end
function module:bar() ... end
return module
end
That is one line changed at the beginning and one
"end" added at the end.
Any internal reference to module:foo will be the same
in both chunks.
Am I missing something?
Let me reiterate that I am not proposing this because
of global namespace
pollution, although I don't like having a lot of stuff
in globals. I am
proposing it because it makes sandboxes easier, and
because it lets me
load two implementations/versions of the same module
at the same time.
Still, not having to use long.complicated.module.names
all the time is a
big plus: I like module systems like Dylan's for exactly
that reason.
The module namespace can be hierarchical, but my references
to libraries
are simply what I chose to use in my little snippet
of code:
local mime = require "com.nehab.diego.mime"
local foo = mime.decode(...) -- or whatever
I'm not sure I understand the issue about mime.lua
and mime.dll. It seems
they are both needed, mime.lua won't work without
mime.dll. So it is logical
(to me) to require the .dll and have it include mime.lua
as a string
constant. That makes for one less file to have to
worry about when installing
the mime library. But I suppose not everyone would
agree with that: it does
make editing the lua part of the mime module more
work. (Nothing that a
makefile couldn't fix, though.)
I can't resist pointing out that the convention of
handing a module creation
function a table rather than having it make its own
is ideal in the case that
you want to combine C and Lua functions in the same
module table: one of them
can call the other one's instantiation function with
the table. So there's
another application for the paradigm.
In any event, you could use hierarchical naming just
as easily as two require
functions; these two lines are pretty similar:
requirelib "mime"
require "mime.c"
Finally, I think the code I presented demonstrates
how easy it is to handle
static vs. dynamic libraries using this approach.
I know it was a lot of
uncommented code, and I threw it together without
making sure that it all
works :(, but it's only a couple of pages in the end.
If you look closely at that code, you will see that
it keeps the module
instantiation function as the value in a weak-keyed
table whose key is
the module table itself; the module table, in turn,
is kept in the module
cache. This means that a module once imported into
a cache will not get
garbage collected until the cache is no longer referenced.
If these caches
correspond to sandboxes (which was my intention),
that will be precisely
correct, as far as I can see.
There is no issue with static libraries being accidentally
unloaded
because the static library is never loaded with loadlib
and thus does not
have an associated library handle. And all of this
without even Edgar's
quite clever upvalue mod.
R.