Reputation: 16075
I've read PIL and the ModulesTutorial on creating modules but I'm having trouble require()
ing them correctly.
Here is my setup:
-- 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
And:
-- File ./snowplow.lua
local set = require( "lib.3rdparty.set" )
module( "snowplow" )
local SUPPORTED_PLATFORMS = set.newSet { "pc", "tv", "mob", "con", "iot" }
Then if I run snowplow.lua
:
lua: snowplow.lua:4: attempt to index local 'set' (a boolean value)
stack traceback:
snowplow.lua:4: in main chunk
[C]: ?
What am I doing wrong in my module definition - what is the boolean exactly? Also, if I append a return _M;
at the bottom of my set.lua
, then everything starts working - why?
Upvotes: 3
Views: 3935
Reputation: 1
require("lib.moduleName")
local moduleName = moduleName
I'm not sure why Lua returns a boolean when you require a module on a different directory, but it seems the module is correctly set on the the global variable. So I simply used that and put it on a local variable with the same name.
Upvotes: 0
Reputation: 23737
true
is usually returned by require
if module
function is not used inside module and module code doesn't return a value.
But anyway it seems strange.
-- 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
So, you can simply use global variable set
instead of local set
assigned a value returned by require
.
UPD :
It is recommended to avoid using module
function and always return
your table at the end of your module. In that case the whole picture is just fine:
-- 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 :
Problem disappears if you replace module( "set" )
with module('lib.3rdparty.set')
.
So, each module must remember its relative path.
Now you could access it either by calling require'lib.3rdparty.set'
or by reading global variable lib.3rdparty.set
- the result would be the same.
Upvotes: 2