package.path未正确设置

时间:2014-01-02 21:12:32

标签: lua shared-libraries

我有一种情况,根据我定义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)我会咆哮另一棵树。我正在使用一个框架。也许它有一个错误......现在正在测试它。

1 个答案:

答案 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感兴趣,它允许您设置错误处理函数;这可能会导致更清晰的代码。