Modules from the ground up

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

Modules from the ground up

Sean Conner

  Assume a virgin Lua state:

        L = luaL_newstate();

  One can load a Lua script into this state and execute it:

        luaL_loadfile(L,"/tmp/foo.lua")
        lua_call(L,0,LUA_MULTRET);

  But what you can do is severely limited (no io, no math, etc).  I started
writing a long post starting from this point, and to summarize, I ended up
with the following:

        A function called _REQUIRE() [1] that pretty much does what
        require() does (finds modules and loads them), but also adds the
        identifier used to load the code into an internal table (unnamed,
        but think package.loaded[]) and returns whatever the module returns.
        It does not, however, modify the global state.

        A function called _MODULE() [2] that just sets a new environment
        (like module()) but does not take a name (no need for it).  That's
        it.

  So now our virgin state would be created thusly:

        L = luaL_newstate();
        lua_pushcfunction(L,luaM__REQUIRE);
        lua_setglobal(L,"_REQUIRE");
        lua_pushcfunction(L,luaM__MODULE);
        lua_setglobal(L,"_MODULE");

  Code wanting to be a module would do:

        ----[ sample.lua ]---------

        local string = _REQUIRE("string")
        _MODULE()
        function split(s,delim) ... end
        function wrap(s,margin) ... end
        function trim(s) ...end

        ----[ end ]---------

  And code wanting to use this as a module would do:

        local foo = _REQUIRE("sample")

        x = foo.split(...)

  My intent was to start with as a restricted environment as possible and
build things up from there.  Unfortunately (or fortunately, depending upon
your point of view) I went on vacation before I could finish the post, and
thus, I'm posting a rather simplified version of it (it's probably better
for it).  

  Just what *is* the minimum required to support modules?  And how difficult
does it need to be?

  -spc (So, start from luaL_newstate() and go from there ...)

[1] named thus to distinquish it from the standard require() function
        and two, it needed to be added to the global Lua state and three,
        variables starting with an underscore and upperletters is reserved
        for Lua.

[2] Named for similar reasons

Reply | Threaded
Open this post in threaded view
|

Re: Modules from the ground up

Dirk Laurie-2
2011/10/21 Sean Conner <[hidden email]>:
>
>  Assume a virgin Lua state:

Uh-oh!  I've been slammed for that!  Rather assume a pristine Lua state.

D.

Reply | Threaded
Open this post in threaded view
|

Re: Modules from the ground up

Miles Bader-2
Dirk Laurie <[hidden email]> writes:
>>  Assume a virgin Lua state:
>
> Uh-oh!  I've been slammed for that!

wut?

-miles

--
Insurrection, n. An unsuccessful revolution.

Reply | Threaded
Open this post in threaded view
|

Re: Modules from the ground up

Michael Richter
On 21 October 2011 13:57, Miles Bader <[hidden email]> wrote:
Dirk Laurie <[hidden email]> writes:
>>  Assume a virgin Lua state:
>
> Uh-oh!  I've been slammed for that!

wut?

There are uneducated people who don't realize that the word "virgin" can be used outside of a sexual context. 

--
"Perhaps people don't believe this, but throughout all of the discussions of entering China our focus has really been what's best for the Chinese people. It's not been about our revenue or profit or whatnot."
--Sergey Brin, demonstrating the emptiness of the "don't be evil" mantra.
Reply | Threaded
Open this post in threaded view
|

Re: Modules from the ground up

Philipp Janda
In reply to this post by Sean Conner
On 21.10.2011 06:10, Sean Conner wrote:

>
> [...]
>    Code wanting to be a module would do:
>
> ----[ sample.lua ]---------
>
> local string = _REQUIRE("string")
> _MODULE()
> function split(s,delim) ... end
> function wrap(s,margin) ... end
> function trim(s) ...end

You forgot 'return _ENV'! Since _MODULE does not get the module name, it
cannot pass the exported definitions via 'package.loaded[ name ]'. So
you must pass the exported definitions via 'return'.

If you add 'return _ENV', _MODULE() becomes '_ENV = {}'.

>
> ----[ end ]---------
>


Philipp


Reply | Threaded
Open this post in threaded view
|

Re: Modules from the ground up

Sean Conner
It was thus said that the Great Philipp Janda once stated:

> On 21.10.2011 06:10, Sean Conner wrote:
> >
> >[...]
> >   Code wanting to be a module would do:
> >
> > ----[ sample.lua ]---------
> >
> > local string = _REQUIRE("string")
> > _MODULE()
> > function split(s,delim) ... end
> > function wrap(s,margin) ... end
> > function trim(s) ...end
>
> You forgot 'return _ENV'! Since _MODULE does not get the module name, it
> cannot pass the exported definitions via 'package.loaded[ name ]'. So
> you must pass the exported definitions via 'return'.
>
> If you add 'return _ENV', _MODULE() becomes '_ENV = {}'.

  I was trying to come up with a way around that.  I'm still thinking.

  -spc


Reply | Threaded
Open this post in threaded view
|

Re: Modules from the ground up

Sean Conner
In reply to this post by Sean Conner

  Okay, assume a pristine Lua state:

        L = luaL_newstate();

  What would one need to support modules in a pristine state?  

  Some other thoughts---even if require()/module() no longer pollute the
global namespace, you *still* need to be concerned about module names.  For
instance, assume there's a "graph" Lua module that implements various graph
algorithms, and also assume there's a "graph" Lua module that implements
various ways to generate a graphic image of data (say, a bar graph, pie
chart, etc.).  Suppose further I want to use "graph" module to generate
various graphs and display performance characteristics using the "graph"
module to display the results.

  Without changing the code to "graph" and "graph", can it be done?  Is
there a way to do such a thing?  

  -spc