lua-users home
lua-l archive

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

I'm still pondering Roberto's proposal. It's certainly an improvement over
what is available right now.

For consideration in the discussion, I'm also going to throw out a summary
of the properties of our homebrew package system. I think I've enumerated
some of this before, but not in this detail. The code right now isn't
cleanly severable enough to offer up, but we might be able to work on that
given sufficient interest. (The interest needs to be real since it will
require talking to lawyers...)

* We group things into "bundles". These more or less map to MacOS X bundles,
but are essentially just directories.

* A bundle can offer to supply one or more "namespaces". It does so via a
special info.lua file which is a Lua file describing the properties of the
package. The idea is that one can scan and even cache info.lua files. For
example, an Info.lua file might look like the following:

    return {
        exports = {
            "namespace1" = "filename1",
            "namespace2" = "filename2"

* Namespace names are essentially arbitrary strings. No hierarchical package
structuring is assumed though it can be provided by using names

* Namespaces are imported via 'import "namespace"'. This can return an
arbitrary Lua value.

* import looks to see whether the namespace is already loaded and if not it
finds a bundle which exports that namespace and loads and executse the
appopriate file from within the bundle. We could easily handle multiple
types of file by trying various extensions on the file name. I don't recall
whether we do or not in the present implementation.

* We handle native code by assuming a specific block of code associated with
a bundle. The export above then becomes
"namespace" = "C:function_name"'. This allows multiple entrypoints to native
code. This could easily be modified to allow named native code files as well
though I think it would still be good to retain the ability to name
functions within them.

* Code within a bundle gets executed in an environment that references the
bundle so that other resources such as images can be found. We do this via a
new "global" _B defined in the environment for the bundle code.

* We define a bundle-specific version of require so that a bundle can load
itself piecewise without exposing those pieces to the rest of the world. It
might be nice to make this more uniform by for example redefining the
namespace import function within a bundle to see the private namespaces.

* When a namespace provider function runs, it can actually export multiple
namespaces. In particular, it can export the same value under multiple names
so that one can export the same thing as "myNamespace" and "myNamespace_v2".
This way, code that needs version 2 can explicitly import it but the
exporting code doesn't have to build separate structures.

* We do not add namespaces to the global namespace on the basis that this
potentially encourages the bad habit of relying on some other piece of code
to have done the import.

If adding to the globals was really useful, at the expense of not supporting
hierarchical names, one could define a metamethod on the globals table to
make import automatic. We have not done so.

* We disallow cyclic import.

* import provides an extended form:

        import( "namespace", "entry1", "entry2", ... )

This returns not just the namespace but looks up the values in the result
returning them as extra results and asserts if they are not defined. import
also asserts if it can't  obtain the namespace, though I could see
redefining it to return nil. For example:

    local _, addObserver, notifyObservers =
            import( "observations", "add", "notify" )


One nice thing about the info.lua files is that they make it easy to add
support for other things like looking for all of the file format filters
simply by having those get reported as extra entries.