lua-users home
lua-l archive

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


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