我有一种情况,根据我定义package.path的位置,我的代码失败了。我不明白为什么。
我有以下文件结构:
/usr/share/zaf/mytestapp/main.lua
/usr/share/zaf/mytestapp/lib/user.lua
/usr/share/zaf/mytestapp/lib/admin_user.lua
有效的代码
在main中,我有以下代码:
module (..., package.seeall)
package.path = package.path .. ';/usr/share/zaf/mytestapp/?.lua'
local user = require "lib.user"
list_devices = function(user_id, enduser, start_record, record_count)
local devices = {}
local success
local res, err = pcall(function()
if enduser then
success, devices = user:getDevices(user_id)
end
end) --end pcall
return devices
end
此代码有效...系统能够找到user.lua并返回设备列表。
无效的代码
我想更改代码,以便仅在之后 加载库 我知道它是什么类型的用户。请注意我是如何将实例化用户对象的代码的位置移动到'if'语句中的,但是我将package.path行保留在原来的位置。
module (..., package.seeall)
package.path = package.path .. ';/usr/share/zaf/mytestapp/?.lua'
list_devices = function(user_id, enduser, start_record, record_count)
local devices = {}
local success
local res, err = pcall(function()
if enduser then
local user = require "lib.user"
success, devices = user:getDevices(user_id)
else
--admin
local admin_user = require 'lib.admin'
admin_user:get_devices()
end
end) --end pcall
return devices
end
此代码失败,因为它无法再找到lib.user模块......我不明白为什么。我还在学习lua,所以如果这是一个真正的问题,你将不得不原谅我。 如果我将package.path行移动到if语句内部,它就可以......就像这样:
if enduser then
package.path = package.path .. ';/usr/share/zaf/mytestapp/?.lua'
local user = require "lib.user"
success, devices = user:getDevices(user_id)
else
--admin
local admin_user = require 'lib.admin'
success, devices = admin_user:get_devices()
end
我不想多次定义package.path但是......
任何建议将不胜感激。
感谢。
编辑1
我想我知道发生了什么......但我不知道为什么或如何解决它。如果我将package.path定义设置在文件的顶部,那么当代码进入list_devices()方法时,package.path将重置为默认值。我通过添加一个调试语句对此进行了测试,该语句将package.path的内容转储到失败的代码的if语句中。它不再有我附加的路径,即“/ usr / share / zaf / mytestapp /?。lua”。
这解释了为什么我无法实例化该对象。因为我似乎没有做一些明显错误的事情,(我不确定在bc之前我是不是在lua)我会咆哮另一棵树。我正在使用一个框架。也许它有一个错误......现在正在测试它。
答案 0 :(得分:1)
您显示的代码没有任何问题。问题的根源是代码未显示,结合使用pcall
来捕获错误以支持返回代码,因此如果您没有采取适当的预防措施,尽管匿名函数出错,您的脚本仍可继续。这可能很有用但也很危险(如果没有适当的检查)。
即,我运行以下main.lua
:
package.path = package.path .. ";testreqdir/?.lua"
list_devices = function(end_user)
function test()
if end_user then
print('requiring')
local user = require "testlib.user"
user:test()
end
end
local status, errMsg = pcall(test)
end
list_devices(true)
在testreqdir/testlib
文件夹中,user.lua
就是:
print('user loaded')
return {
test = function()
print('hello', arg[0])
end
}
这会产生以下输出:
C:\Users\me>lua testrequire.lua
requiring
user loaded
hello testrequire.lua
如果我注释掉package.path
行,因此未找到user.lua
模块,则输出如下,并且没有迹象表明在require
的调用中发生错误,由于pcall
:
C:\Users\me>lua testrequire.lua
requiring
最有可能当你在函数内部需要user.lua
时,会发生错误但被pcall
困住并作为代码返回。因此,暂时删除pcall
,以便获得追溯。此外,如果您坚持使用pcall
,则应添加代码以检查错误的返回代码并采取适当的措施。您可能对xpcall
感兴趣,它允许您设置错误处理函数;这可能会导致更清晰的代码。