package.path没有被正确设置。

我遇到一个情况,取决于我在哪里定义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将被重置回默认值。我通过添加一个调试语句来测试这一点,该调试语句在代码失败的if语句中转储了package.path的内容。它不再具有我附加的路径,即"/usr/share/zaf/mytestapp/?.lua"。

这就解释了为什么我不能实例化对象。由于似乎我没有明显错误(以前我不确定,因为我是Lua的新手),我将在另一棵树上吠。我正在使用一个框架。也许它有一个bug...正在测试它。

点赞
用户869951
用户869951

你展示的代码没有问题。问题的根源在于未显示的代码与使用 pcallpcall 可以捕获错误并返回一个返回代码,使你的脚本即使在匿名函数中出现错误时仍然能够继续运行,但是这既有用又危险(如果没有适当的检查)。

例如,我运行以下 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 模块无法找到,输出将如下所示,由于 pcall,没有指示调用 require 时发生错误:

C:\Users\me>lua testrequire.lua
requiring

最可能的是,当你从函数中要求 user.lua 时,会发生错误,但被 pcall 捕获并作为代码返回。因此,暂时删除 pcall,以便获得回溯。此外,如果您坚持使用 pcall,您应该添加代码来检查 err 的返回代码并采取适当的措施。您可能会对 xpcall 感兴趣,它允许您设置错误处理程序函数;这可能会导致更清晰的代码。

2014-01-03 04:41:58