[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: changes in 'require'
- From: Mike Pall <mikelu-0507@...>
- Date: Wed, 13 Jul 2005 18:34:37 +0200
Hi,
Roberto Ierusalimschy wrote:
> What do you mean by "optmized"?
>
> If it is going to use a.b.c.xxx, why not start trying it? It eliminates
> the need to "retry" a.b.c.d. It is much simpler (less steps, no ifs):
But failure on the 'regular' require (what 51w6 currently does)
is rare. Doing the xxx/meta/whatever retry _after_ the regular
request minimizes the search overhead. And this retry is only
needed on the first reference to a packaged submodule. Afterwards
all of them should be either in package.preload (or package.loaded)
and will be found without a retry.
If you do it the other way round, you always need to search the
whole hierarchy of xxx/meta/whatever modules (making N*(length of
Lua path + length of C path) filesystem requests), even when it's
just a plain module in the filesystem or in package.preload.
We should aim to minimize the search overhead for the common case.
The logic can be simplified by adding a 'package' loader to
package.loaders and using recursion. Untested pseudo-code follows:
package.loaders[4] = function(name) -- loader_package
if has_suffix(name, "_pkg") then return end -- ignore recursive requests
local head = name
repeat
if pcall(require, head .. "_pkg") and package.preload[name] then
return package.preload[name]
end
head = strip_last_level(head)
until head == nil
end
[Of course in the real C code you'd call a helper function that
does the search through the loaders table and returns success/failure
instead of using pcall(require,...).]
This will try
a.b.c_pkg
a.b_pkg
a_pkg
_pkg
when 'a.b.c' is requested (and is not found with the plain loaders).
Back to our canonical LuaSocket example: you can put everything
into 'socket_pkg.so' and it will be found both for require "socket"
and for require "socket.foo". You can even put all your modules
into '_pkg.so' (the root package).
Bye,
Mike