lua-users home
lua-l archive

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


Hello,

I'm looking for the simplest to achieve modularity in a practicle manner. Ideally, here is what I would like:

1. A module is a file of code, and conversely -- or a file plus all what it requires; I'm ready to pay the price of introducing all of a module's top symbols with 'local', for that.

2. A module explicitely exports; the obvious way to do that seems to be 'return that'.

However, when a module is a pack of functionality (like math) rather than a big composite piece of data, or a major type, then it's elements are encapsulated in 'that. This is a good in the general case; it does not always lead to important code as in file.read vs file_read, and often clarifies the code as in file.read bs fread.

3. But, a good organisation of code typically leads to "separation of concerns" where (client) code module deal with a major aspect of a software, and thus require there, and only there, a dedicated library. Examples may be UI design importing a GUI framework, definition of a parser importing a parsing lib, complex number calculation importing a Complex type... In this case (provided the original names are well designed), it would be a very helpful feature for simplicity and clarity of code to have all of a module's exported symbols at the toplevel of the requiring one.

This seems incompatible with 1. and 2., maybe. The only way I can see is
   open_table = function (t) for k,v in pairs(t) do __ENV [k] = v end end
However, this would in fact import a lib's symbols into _G, by default. To have meet other criteria, we would have to make every module live in a custom, closed, environment.

Do some of you have a similar practice? How would you do that?

Denis

PS: for user-scripting, all is fine I guess, since one would let them code inside a kind of sandbox __ENV anyway. PPS: I'm thinking at a practice where one would define their everyday "standard toolkit" with all of regularly used builtin features and custom tools, and put them into a table intended to be used as environment rather then module. (With a hook to _G for exceptional use cases, or _G's features redefined on the module table.) Then, do
   __ENV = require "stdkit"
instead of just
   require "stdkit"