[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Nested mobules
- From: Mike Pall <mikelu-0505@...>
- Date: Sat, 21 May 2005 14:59:41 +0200
Hi,
stukov@gala.net wrote:
> Is it posible to create nested modules using lua 5.1w6 ?
Yes, by using hierarchical module names. This is the designated
way to organize packages:
Module name Path relative to install directory
-------------------------------------------------------
packageA.init packageA/init.lua
packageA.module1 packageA/module1.lua
packageA.module2 packageA/module2.lua
packageB.init packageB/init.lua
packageB.module1 packageB/module1.lua
packageB.module2 packageB/module2.lua
* You can just use
require "packageA"
to load package A, because package.path has both ?.lua
and ?/init.lua (relative to the install directory).
Note: this particular feature only works relative to the
install directory, but not relative to the current directory.
Have a look at the full path with:
lua -e 'print(package.path)'
* From inside a package you can load the other modules
of the same package by giving the full module name:
require "packageA.module1"
Note: At least from */init.lua you _have_ to use the full
syntax. This is because 'module "packageA"' cannot know that
this is the name of a package (and not a plain module) and
that the name should be split differently.
* From within other modules inside a package you can use
relative syntax (but you have to put module(...) before that):
local module2 = require(_PACKAGE.."module2")
Submodules with the same names in different packages do not
conflict because their module tables are stored in a different
hierarchy (under a global + subtables with the same name as
the submodule name).
Example:
--Application:
require "foo"
require "bar"
print(foo.xyz.var)
print(bar.xyz.var)
--foo/init.lua
module "foo"
require "foo.xyz"
--foo/xyz.lua
module(...)
var = "set by foo.xyz"
--bar/init.lua
module "bar"
require "bar.xyz"
--bar/xyz.lua
module(...)
var = "set by bar.xyz"
Here are a few recommendations/tips:
* Use the following syntax to get convenient access to modules
and/or submodules:
local foo = require "foo"
local bar = require "abc.def.ghi.bar"
This caches the module table in a local variable (it's faster, too).
* The package initializer should load the other submodules, but
add only minimum functionality itself. The package initializer
should use an explicit name for module(), i.e. module("foo")
and _not_ module(...) (because it may be loaded under two
different names).
* Package submodules that depend on functionality from other
package submodules should explicitly require the other submodules:
local module2 = require(_PACKAGE.."module2")
... just in case the submodule is loaded independently from
the package.
* Package submodules that cannot be loaded independently should
require the package initializer first:
module(...)
local package = require(_PACKAGE.."init")
This works fine, because the module system can handle circular
dependencies. But be careful when you cache elements from module
tables in locals -- caching the module table itself is ok.
* Yes, you can use deep nesting, e.g.: module "foo.bar.baz"
The module system treats everything up to the last dot as the
package name (_PACKAGE = "foo.bar.") and everything after that
as the submodule name (_NAME = "baz").
* If you require explicit access to your own (sub)module table,
use _M. Newly created globals (e.g. global function definitions)
are implicitly stored there (var=1 is the same as _M.var=1).
Bye,
Mike