lua-users home
lua-l archive

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

On Thu, 2011-01-20 at 08:23 -0500, Steve Litt wrote:
> Hi all,
> I think I discovered a possible improvement to the documentation in the Lua 
> 5.1 Reference Manual's description of lua_call() regarding calling of a 
> specific function in a Lua script. 
> For a newbie (me, for instance), I don't think this documentation is clear 
> enough about what you use for the nargs argument to lua_call() and therefore 
> lua_pcall. At one point it says:
> "Finally you call lua_call; nargs is the number of arguments that you pushed 
> onto the stack."
> While this is technically correct, the newbie might interpret this as the 
> number of arguments taken by the Lua function. It isn't. It's that number of 
> arguments plus one more that's used by the function name.

No, 'nargs' is exactly that - the number of ARGUMENTS you want to pass
to the function. You do not pass the function "name". Maybe this is a
bit confusing when coming to a language with first-class functions, but
you actually push the function itself on the stack.

> So if you interpret nargs as the number of args required by the Lua function 
> and do this:
>     lua_getglobal(L, "tellme");
>     if (lua_pcall(L, 0, 0, 0)) 
> 	bail(L, "lua_pcall() failed"); 
> You get this at runtime:
> =================
> slitt@mydesk:~$ ./callfunc
> In C, calling Lua
>   lua_pcall() failed: attempt to call a nil value

This is because there is no global named "tellme" (whose value should be
a function).

> Only if you read VERY carefully and concentrate on the documentation's saying 
> "All arguments and the function value are popped from the stack when the 
> function is called" do you get the idea that maybe nargs includes the pushed 
> function name as well as the args required by the Lua function. In that case 
> you do this:
>     lua_getglobal(L, "tellme");
>     if (lua_pcall(L, 1, 0, 0)) 
> 	bail(L, "lua_pcall() failed"); 
> And succeed:
> =================
> slitt@mydesk:~$ ./callfunc
> In C, calling Lua
> This is coming from lua.tellme.
> Back in C again
> slitt@mydesk:~$
> =================

You must have done something to your stack prior to this code, to have
accidentally included a function before this call. Let's take the code
from the manual:

a = f("how", t.x, 14)

Here it is in C: 
     lua_getfield(L, LUA_GLOBALSINDEX, "f"); /* function to be called */
     lua_pushstring(L, "how");                        /* 1st argument */
     lua_getfield(L, LUA_GLOBALSINDEX, "t");   /* table to be indexed */
     lua_getfield(L, -1, "x");        /* push result of t.x (2nd arg) */
     lua_remove(L, -2);                  /* remove 't' from the stack */
     lua_pushinteger(L, 14);                          /* 3rd argument */
     lua_call(L, 3, 1);     /* call 'f' with 3 arguments and 1 result */
     lua_setfield(L, LUA_GLOBALSINDEX, "a");        /* set global 'a' */

At the beginning, the value of the global 'f' is pushed on the stack
(and we expect it to be a function). The call stack right before
lua_call is as follows:

1. function
2. "how"
3. value of t.x
4. 14

Then, you call lua_call(L, 3, 1). Notice that you pass 3 arguments, and
the 3 values from the top of the stack are passed as arguments. After
the call is finished, the 3 arguments are popped, together with the
function (not the "name", there is no such thing as function "name" in
Lua, there are only functions as values of named variables :). One
result is pushed onto the stack by lua_call, the value returned by the
function. This is assigned to the global "a".

You should often check the contents of the Lua stack while learning,
like with the function listed at , to
get an idea how it is working - it is really simple in the end :)