Lazy loading of (sub)modules

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Lazy loading of (sub)modules

Krunal Rao
Hi,

in some libraries I am working on I lazily load "sub-modules", i.e.

local mylib = require "mylib"
local z = mylib.xxx.z -- here the sub-module xxx is loaded which contains z

this is easily achieved via the __index metamethod applied to the mylib table.
In the example above I would have /lua/mylib/xxx.lua required via 'require
"lib.xxx"'.

Everything is good and simple (I just have to add lua files in the mylib dir),
but sometimes sub-modules contain too much code for a single lua file (IMHO and
in my case). At the moment I am solving the issue by having the sub-module (xxx
above) importing everything (z and much more) from a list of lua files to
itself:

-- xxx.lua:
local _M = {}
import(_M, require "mylib.xxx_imp.a") -- implementation not shown here.
import(_M, require "mylib.xxx_imp.b") -- I could use dofile as well, xxx_imp not
"exposed"
...
return _M

This requires me to manually edit the xxx.lua file every time some new
functionality is added to xxx. It would be nice to be able to have some code
that allows me to "import" all the lua files in a given directory (xxx_imp
above) to avoid this manual editing.

I guess this cannot be done via plain lua as it likely requires a library like
lfs. Moreover I am concerned about how to figure out what directory to look
into. I always simply used require, but I clearly cannot rely on it here (I
don't know the lua file-names I would be importing) so I would need to figure
out a way to discover where to look for "mylib.xxx_imp" as a directory.

Experience has shown to me that it's usually a good idea to keep things simple
and not over-engineer them, so I am wondering whether there is a much simpler
solution/approach to the problem I am facing.

Any suggestion is more than welcome :)

Cheers,


Reply | Threaded
Open this post in threaded view
|

Re: Lazy loading of (sub)modules

David Manura
On Mon, Dec 5, 2011 at 5:44 PM, KR <[hidden email]> wrote:

> [...]
> but sometimes sub-modules contain too much code for a single lua file (IMHO and
> in my case). At the moment I am solving the issue by having the sub-module (xxx
> above) importing everything (z and much more) from a list of lua files to
> itself:
>
> -- xxx.lua:
> local _M = {}
> import(_M, require "mylib.xxx_imp.a") -- implementation not shown here.
> import(_M, require "mylib.xxx_imp.b") -- I could use dofile as well, xxx_imp not
> "exposed"
> ...
> return _M
>
> This requires me to manually edit the xxx.lua file every time some new
> functionality is added to xxx.

And what's wrong with doing that?  ;)

Please also note that those deploying your modules might not intend to
install them according to your preconceived file layout.  They might
compile them to bytecode, run bin2c [1], and/or use a bundling
approach like [2].  These would break if you relied on a module
loading technique like lfs.dir.

[1] http://lua-users.org/wiki/BinToCee
[2] http://loop.luaforge.net/release/preload.html

Reply | Threaded
Open this post in threaded view
|

Re: Lazy loading of (sub)modules

Michal Kolodziejczyk-3
In reply to this post by Krunal Rao
On 05.12.2011 23:44, KR wrote:

> It would be nice to be able to have some code
> that allows me to "import" all the lua files in a given directory (xxx_imp
> above) to avoid this manual editing.

How about:
import(_M, require "mylib.xxx_imp")
and then:
-- mylib/xxx_imp/init.lua
require "mylib.xxx_imp.a"
require "mylib.xxx_imp.b"

> I guess this cannot be done via plain lua as it likely requires a library like
> lfs.

You could use io.popen("ls "..DIR.."/*.lua") (or equivalent on Windows)

> Moreover I am concerned about how to figure out what directory to look
> into. I always simply used require, but I clearly cannot rely on it here (I
> don't know the lua file-names I would be importing) so I would need to figure
> out a way to discover where to look for "mylib.xxx_imp" as a directory.

You may use env variables:
$ LUA_PATH=/opt/mylib/?.lua lua myprogram.lua

or:

$ export MYLIB=/opt/mylib; lua myprogram.lua

-- main.lua:
DIR=os.getenv("MYLIB")

Regards,
miko