在Lua中调用require()的模块上的函数会给我返回"尝试对本地变量'x'进行索引(一个布尔值)"的错误信息。

我已经读了 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]: ?

在我的模块定义中我做错了什么 - 究竟是什么布尔值?如果我在 set.lua 的底部添加 return _M;,然后所有东西都开始工作了 - 为什么?

点赞
用户1847592
用户1847592

如果在模块内未使用module函数且模块代码没有返回值,则通常通过require返回true

但是无论如何,这似乎很奇怪。

--文件 m0.lua
module'm0'

--文件 dir1\m1.lua
module'm1'

--文件 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

--输出
table: 0036C8C8
table: 0036C8C8
true
table: 0036B6B0
m0      table: 0036C8C8
m1      table: 0036B6B0
dir1.m1 true

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


更新:

建议避免使用module函数,并始终在模块末尾return您的表。在这种情况下,整个图像就很好了:

--文件 m0.lua
return 'string0'

--文件 dir1\m1.lua
return 'string1'

--文件 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

--输出
string0
nil
string1
nil
m0      string0
dir1.m1 string1

更新2:

如果您将module("set")替换为module('lib.3rdparty.set'),则问题将消失。

因此, 每个模块必须记住其相对路径

现在,您可以通过调用require'lib.3rdparty.set'或读取全局变量lib.3rdparty.set来访问它-结果将相同。

2013-04-13 14:39:38
用户4508586
用户4508586

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


我不确定为什么当你从不同的目录 require 一个模块时 Lua 会返回一个布尔值,但似乎这个模块已正确设置在全局变量上。因此,我只是使用了那个全局变量,并将它放在一个同名的本地变量上。

2015-01-29 18:02:22