lua-users home
lua-l archive

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


Tkank you, I see the light. This is exactly how I thought it *should* work but I could just not reconcile this with the documentation. My problem was one of terminology. For me a "loader" loads things from the outside into the system so I view the loadfile() function as being the loader. So the function/chunk returned from loadfile() has already been loaded and can't be a "loader". Unless of course, it loads something else from the outside world into the system. Therefore my confusion.

Rob Hoelz earlier gave a similar answer but I had the same terminology problem.

Thanks gain,

Robert

----- Original Message -----
> From: "Jerome Vuarand" <jerome.vuarand@gmail.com>
> To: "Lua mailing list" <lua-l@lists.lua.org>
> Sent: Friday, 6 December, 2013 5:15:15 PM
> Subject: Re: Search paths in require/packages
> 
> 2013/12/6 Robert Virding <robert.virding@erlang-solutions.com>:
> > That sounds definitely weird. How do I then tell require *where* to look
> > for the module? So if I write "a = require 'foo'" how does does the
> > loading mechanism know where to look for 'foo'? The default path values
> > imply that requiring a 'foo' will try to find either a foo.lua or an
> > foo/init.lua in a number of different places. This is also described in
> > the package.searchers description, both by referencing
> > package.searchpath() for Lua loader and very explicitly for the C library
> > loader.
> 
> Maybe we should recap each term:
> 
> A module can be two things depending on the point of view. A module
> can be the runtime object that represent a module in the Lua
> interpreter. It's usually a table containing functions, but it can be
> any Lua value. A module can also be the Lua file that defines the
> module (or the DLL file that expose the module). For the sake of
> clarity, let's call the first thing the "module object" and the second
> thing the "module source" (even though it might not always be source
> code). All modules have a "module object", but some may not have a
> "module source".
> 
> A loader is a function, that when called, will return a module object.
> luaopen_string is a C loader. The chunk/function resulting from the
> compilation of socket.lua is a Lua loader.
> 
> A searcher is a function that, given a module name, will look for a
> module source with that name, and create and return a loader for that
> module. There are 4 searchers in a standard Lua interpreter, you can
> add more or remove any of these 4. For example the Lua searcher will
> look for .lua files as module source, and compile them (but not
> execute them).
> 
> require is a function that calls searchers, calls loaders, and manages
> modules.
> 
> > So if the paths are for finding loaders how do I tell where to find the
> > modules? Does that mean I have to give the absolute path for require?
> 
> The paths are to find files, the module source. Then the Lua searcher
> compiles the file, and return the result of the compilation, that is
> the loader for the module. Then require will execute the file (it's
> just a function, require doesn't know it comes from a file), which
> returns the module table.
> 
> Here is a short implementation (without error handling) of all these
> concepts in Lua. Hopefully it will make things a bit clearer.
> 
> local function lua_searcher(modname)
>     local filepath = package.searchpath(modname, package.path, '.', '/')
>     if not filepath then
>         return nil
>     end
>     local loader = loadfile(filepath)
>     return loader
> end
> 
> local searchers = {
>     preload_searcher,
>     lua_searcher,
>     c_searcher,
>     all_in_one_searcher,
> }
> 
> function require(modname)
>     -- check if the module has already been loaded
>     if not package.loaded[modname] then
>         local loader
>         -- call each searcher to find a loader
>         for _,searcher in ipairs(searchers) do
>             loader = searcher(modname)
>             if loader then break end
>         end
>         -- execute the loader
>         local module = loader(modname)
>         -- store the module
>         package.loaded[modname] = module
>     end
>     -- return the module
>     return package.loaded[modname]
> end
> 
> If you answer this please use "module object" or "module source" to
> clearly distinguish what you mean.
> 
>