"Attempt to call global 'pairs' (a nil value)"

2,041 views
Skip to first unread message

Ron Gomes

unread,
Mar 1, 2013, 9:59:25 AM3/1/13
to openre...@googlegroups.com
We have an elaborate URl rewriter written using mod_python with Apache.  We rewrote it in Lua with Apache's mod_lua but the Lua integration in Apache is incomplete and we may not want to deploy this.

I'm iteratively porting it now to use ngx_lua with nginx.  For readability I'm structuring the code as a "main" .lua file that uses "require" to include other code written as Lua modules.  So the main routine uses

local config = require "config"
local cookie = require "cookie"

and so forth.  And the modules all contain their own initial set of "requires", e.g.

local ngx = require "ngx"
local util = require "util"

etc., followed by

module(...)

So far so good, but it seems that in anything other than the "main" code file, an attempt to use "pairs" or "ipairs" to walk a table produces a run-time error like this:

2013/03/01 09:43:24 [error] 28396#0: *1566 lua entry thread aborted: runtime error: /usr/local/openresty/nginx/cookie.lua:37: attempt to call global 'pairs' (a nil value)

I know this is some sort of C binding error but I don't have a good idea about how to correct it.  Can someone suggest something?

I'm running the most recent development openresty bundle (1.2.7.1), built from source using --with-luajit.

Thanks.

Tor Hveem

unread,
Mar 1, 2013, 10:11:17 AM3/1/13
to openre...@googlegroups.com
local pairs = pairs will probably do the trick.


2013/3/1 Ron Gomes <rgo...@consumer.org>

--
You received this message because you are subscribed to the Google Groups "openresty-en" group.
To unsubscribe from this group and stop receiving emails from it, send an email to openresty-en...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Brian Akins

unread,
Mar 1, 2013, 10:13:09 AM3/1/13
to openre...@googlegroups.com
Yet another reason not to use "module()" ...

Ron Gomes

unread,
Mar 1, 2013, 10:16:55 AM3/1/13
to openre...@googlegroups.com
I'll try "local pairs = pairs", thanks.

I thought that using modules was a recommended practice in this context. Is there a better way to structure this if I want the code to live in separate source files?


On Fri, Mar 1, 2013 at 10:13 AM, Brian Akins <br...@akins.org> wrote:
Yet another reason not to use "module()" ...

*****
This e-mail message is intended only for the designated recipient(s) named above. The information contained in this e-mail and any attachments may be confidential or legally privileged. If you are not the intended recipient, you may not review, retain, copy, redistribute or use this e-mail or any attachment for any purpose, or disclose all or any part of its contents. If you have received this e-mail in error, please immediately notify the sender by reply e-mail and permanently delete this e-mail and any attachments from your computer system.
*****

Ron Gomes

unread,
Mar 1, 2013, 10:19:38 AM3/1/13
to openre...@googlegroups.com
Arrgh, I forgot about the stupid boilerplate legal notice that goes out if I reply by mail.  I'll just use the Google Groups Web UI for this from now on.

Brian Akins

unread,
Mar 1, 2013, 2:00:19 PM3/1/13
to openre...@googlegroups.com
On Fri, Mar 1, 2013 at 10:16 AM, Ron Gomes <rgo...@consumer.org> wrote:
> I thought that using modules was a recommended practice in this context. Is
> there a better way to structure this if I want the code to live in separate
> source files?

using modules is common, but module() is evil, IMO. Deprecated in 5.2 as well.

http://lua-users.org/wiki/LuaModuleFunctionCritiqued

Ron Gomes

unread,
Mar 5, 2013, 9:27:02 AM3/5/13
to openre...@googlegroups.com
Got it, thanks.  I rewrote to eliminate the use of module(...), instead using the "local M={}" style, as in fact I had been doing before seeing examples in Lua documentation that seemed to suggest that module() was preferable.

That cleaned up the namespace considerably and made all the "local pairs = pairs" (etc.) definitions unnecessary.

agentzh

unread,
Mar 5, 2013, 2:13:21 PM3/5/13
to openre...@googlegroups.com
Hello!

On Tue, Mar 5, 2013 at 6:27 AM, Ron Gomes wrote:
> Got it, thanks. I rewrote to eliminate the use of module(...), instead
> using the "local M={}" style, as in fact I had been doing before seeing
> examples in Lua documentation that seemed to suggest that module() was
> preferable.
>
> That cleaned up the namespace considerably and made all the "local pairs =
> pairs" (etc.) definitions unnecessary.
>

Just ensure that you properly check attempts of writing to undeclared
Lua variables, which could lead to unexpected data sharing across the
concurrent requests, which is dangerous (consider that user A may see
user B's data occasionally) and hard to debug. See

http://wiki.nginx.org/HttpLuaModule#Lua_Variable_Scope

Also, because the environment table (and thus globals) of each request
is transient, ensure that you always local-ize variables (or
functions) that you actually use in your module.

Personally I've found the "module(...)" notation handy and I've been
using it in all of my lua-resty-* libraries :) But package.seeall is
really bad and should always be avoided.

Best regards,
-agentzh

Brian Akins

unread,
Mar 7, 2013, 11:47:34 PM3/7/13
to openre...@googlegroups.com
On Tue, Mar 5, 2013 at 2:13 PM, agentzh <age...@gmail.com> wrote:
> Just ensure that you properly check attempts of writing to undeclared
> Lua variables,

I use a version of "strict.lua" that catches that. You can find a few
versions on the net.

I used Lua before module(), so I never really got used to using it
when the community decided it was a "bad thing." While the _M style
is a bit clunky, it is much more explicit, IMO.

--Brian
Reply all
Reply to author
Forward
0 new messages