[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: Re: Why does luaL_openlibs invoke the interpreter?
- From: Dustin Juliano <velusdarkbind@...>
- Date: Sun, 8 Feb 2009 12:03:54 -0500
Steve Johnson wrote:
For another reason, look into luaopen_io (and then the rest of the
library, I guess). Once the function is in Lua you can alter its
environment. This makes it easy to load a lot of functions and
objects with shared state. http://lua-users.org/lists/lua-l/2005-04/msg00129.html
Also, like the point about the stack, you're spared some cleanup
effort, since you don't have to save and restore the original
Yes, this is an excellent point and is most close to answering my
question. I indicated in my previous message that I saw that these
luaopen_* routines were made to be called from within Lua and not from
C. You came a step closer to answering my question by reminding me
about the environment concept. I then went and re-read the environment
section in the manuals.
So, this is primarily about the internals of Lua. Its all about
scoping. These functions can declare local values in their functions,
but they have to be explicitly declared as 'local'. If they do not,
they augment the global environment; which affects all other chunks/
functions to come. This can clutter the namespace or cause collisions
that this environment method avoids.
Coming from an object oriented perspective: When Lua loads these
libraries, some of them have a need for shared variables. This could
be thought of as member data. Now, they do not want this member data
available to the rest of the scope (global environments). So, in order
to make this possible, it has to make a separate environment.
Why not load these items into the table it creates for the functions?
Is this setting of the environment a convenience, in this case? One
which, that allows routines to push variables into the global (now
private) environment without concerning itself with the name of the
table? Why use such, apparent obfuscation, in manipulating these
environments when tables injection provides this ability?
After all, when the library is loaded, it is in a nice neat table with
all its functions available as indice|name|key of that table.
Sometimes, yes, it makes an additional global item, like print, or
loadlib (if configured).
Sorry if these questions are strange. I am not trying to just use Lua
(thats easy!) I am trying to fully understand its engineering--how it
Alex Davies wrote:
I'd say the main reason is is that they can push arbitrary number of
results on to the stack. Ie base pushes 2, and the rest 1. Future
packages may push 0 or 30. Did you notice that your modified
function messes the stack? :). And should Lua ever have more then
20packages, or a package which pushes lots of results, it'll cause a
Lua stack overlua. The call is just proper stack handling - you
specify how many results you want, you know where the stack is after
Indeed, when called from C it causes a problem. During my experiment I
registered luaL_openlibs as a Lua C function. I did this by making it
a Lua C function and modifying its prototype. Then in my host
application I called lua_register(L, "init", luaL_openlibs), I then
executed it from Lua and it ran without incident. I did modify the
luaL_openlibs to return 0, which truncates the return stack, as
indicated in the documentation.
This was all just an experiment to learn and probe the internal
workings of Lua. The reason I made this change was to see if it was
possible to make the call to luaL_openlibs a Lua script writer's
decision, rather than a hard coded one.
Steve Johnson answered the question as to why, in this particular
library (the Lua standard lib), it wants to be called from Lua and not
just directly injected as table values. Perhaps with this internal
library loading mechanism exposed, it may be able to realize a way to
have Lua receive information about the underlying structure of an
implementation, its need for private scope, and more, without having
to specify those programatically as a Lua script, within the host
implementation; because, it is possible to modify the environment of a
function from within Lua itself. Again, why do it on the library side?
And about private scope, what these environments are really talking
about are very similar to encapsulation. Even if the variables are
available to the table, which represents that member data, it is still
possible for any function in Lua to access those variables in said
table. So how do we really hide member data in Lua?
Alex Davies wrote:
Anyway, I'm curious why you're worried about the extra function
If via some scenario I can't imagine it's become a bottleneck, you
could replace thepushcfunction, pushstring, and call with a regular
c call and a lua_settop(L, 0), at the
cost of some more ambiguity and less consistency with Lua :).
It was not about the overhead or speed or any optimization. It was
trying to understand why a C library for Lua would invoke Lua to call
that C library for its initialization, as part of that C library.
This is a circular logic that did not make sense to me. I understand
it now, but I still find it to be obfuscated.
Thanks for all the answers! I hope to hear back on the new questions I