在Lua中的require()d模块上调用函数给我“尝试索引局部'x'(布尔值)”

时间:2013-04-13 13:22:45

标签: module lua

我在创建模块时已阅读PIL和ModulesTutorial,但我无法正确require()这些模块。

这是我的设置:

-- File ./lib/3rdparty/set.lua
local ipairs = ipairs
module( "set" )
function newSet (t)
  local set = {}
  for _, l in ipairs(t) do set[l] = true end
  return set
end

-- File ./snowplow.lua
local set = require( "lib.3rdparty.set" )
module( "snowplow" )
local SUPPORTED_PLATFORMS = set.newSet { "pc", "tv", "mob", "con", "iot" }

然后如果我运行snowplow.lua

lua: snowplow.lua:4: attempt to index local 'set' (a boolean value)
stack traceback:
  snowplow.lua:4: in main chunk
  [C]: ?

我在模块定义中做错了什么 - 究竟是什么布尔值?另外,如果我在return _M;的底部添加set.lua,那么一切都会开始工作 - 为什么?

2 个答案:

答案 0 :(得分:2)

如果模块内部未使用true函数且模块代码未返回值,则require通常返回{p> module。 但无论如何它似乎很奇怪。

-- file m0.lua
module'm0'


--file dir1\m1.lua
module'm1'


--file test.lua
print(require'm0')
print(m0)

print(require'dir1.m1')
print(m1)

for k,v in pairs(package.loaded) do
   if k:match'm%d' then print(k, v) end
end


--output
table: 0036C8C8
table: 0036C8C8
true
table: 0036B6B0
m0      table: 0036C8C8
m1      table: 0036B6B0
dir1.m1 true

因此,您可以简单地使用全局变量set而不是本地set分配require返回的值。


UPD:
建议避免在模块末尾使用module函数并始终使用return表。在这种情况下,整个画面很好:

-- file m0.lua
return 'string0'


--file dir1\m1.lua
return 'string1'


--file test.lua
print(require'm0')
print(m0)

print(require'dir1.m1')
print(m1)

for k,v in pairs(package.loaded) do
   if k:match'm%d' then print(k, v) end
end


--output
string0
nil
string1
nil
m0      string0
dir1.m1 string1

UPD2:
如果将module( "set" )替换为module('lib.3rdparty.set'),问题就会消失 所以,每个模块必须记住它的相对路径 现在您可以通过调用require'lib.3rdparty.set'或通过读取全局变量lib.3rdparty.set来访问它 - 结果将是相同的。

答案 1 :(得分:0)

require("lib.moduleName")
local moduleName = moduleName

我不确定为什么Lua在需要不同目录上的模块时返回一个布尔值,但似乎模块在全局变量上正确设置。所以我只是使用它并将它放在一个同名的局部变量上。