lua-users home
lua-l archive

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

In my understanding, we all agreed that most parts of a good module
system can be done in Lua itself. But such system can become quite
complex and even may use non-standard facilities (e.g. use of timestamps
to re-load modules that have been modified since they were loaded;
or hierarchical namespaces mapped to directories hierarchies, as in
Python). Therefore, it would be a good idea to provide it outside the
main distribution, through libraries and conventions.

Another thing we agreed is that the standard libraries should come packaged
inside tables, like all other libraries.

However, (at least) two problems remain. The first one is bootstraping.
If the module system depends on a library, how we are going to load that
library? One solution is to put a simple system inside Lua (such as the
current "require") and then use it to activate a more powerful system (that
can re-define "require").

The second is that there is no easy and simple way to avoid using
the dot notation for every reference to an "imported" object. Then I
presented an idea we have been discussing before (the "mechanism that
forces variable declarations").

The mechanism is as follows: first, we start with the "obvious" global

  global a,b,c

But then we add an optional item to the declaration, that states in what
table those "globals" live (yes, it is strange, "global" does not declare
globals anymore... but let us forget that for now). So, if you put functions
'b' and 'c' in a module "m", you can access them directly after the
following declaration:

  global (m) b, c

Roughly, that translates to "local _t = m", and then any access to b (or c)
is translated to "_t.b" (or _t.c). Instead of a list of names, we can also
use a single "*", which means a default for all non-declared globals.

There are many uses for such declarations. First, something like

  global (nil) *

disables access to any non-declared variable ("forces variable declarations").
Something like

  global ({}) *

puts any non-declared variable in a new (private) table. Something like

  Public = {}
  global ({}) *
  global (Public) a,b,c

puts all new names into a private table, but a,b and c, that go to the
public table. (This builds something similar to my proposal for modules,
but you do not have to prefix all names with "Public." or "Private.".)

A little more complex example is

  global (metatable({}, {index=globals()})) *

That puts all new names in a private table, but inherits all global names.

-- Roberto