lua模块没有加载库

时间:2013-12-17 21:10:33

标签: module lua

背景资料:

我只是lua的新手,我正在努力了解模块是如何工作的。但我正在尝试将预先存在的模块加载到新脚本中,并从命令行运行此脚本。

代码:

我有一个名为main.lua的文件,看起来像这样:

module (..., package.seeall)
-- Load libraries
require("luasql.postgres")
require("luasql.sqlite3")

local connect_to_db = function()
   if not global_con then
      env = assert (luasql.postgres())
      global_con = assert (env:connect(databasename, databaseUser, databasepassword, databaseserver))   
      return true
   else
      return false 
   end
end

update_widget = function (parm1, parm2, parm3)
  local connected = connect_to_db()         
  if connected then
     -- do something else
     return true
  end
end -- end function.

我现在正在尝试为此模块创建一个测试脚本。我在一个单独的lua文件中有以下逻辑:

package.path = '/usr/share/myapp/main.lua;'
local my_object = require("main")

print my_object.update_widget

问题:

当我尝试运行测试脚本时出现以下错误:

attempt to call field 'postgres' (a table value)

它失败的行是在connect_to_db()方法中,我尝试创建一个环境变量:

env = assert (luasql.postgres())

到目前为止我尝试了什么:

  1. 我修改了测试脚本中的package.path以匹配main.lua使用的内容。我这样做是通过执行main.lua的“常规”方式 - 由Web应用程序驱动 - 并将package.path的内容转储到日志文件中。 我已经从日志文件中复制了路径并将其用作我的测试脚本中的package.path值...当然,我必须通过添加一个额外的条目来修改它 - 一条通向main.lua的路径。
    但除此之外,包路径是相同的。

  2. 我在main.lua中添加了print语句,以证明它正在进入update_widget方法......而且它只是没有尝试创建postgres。

  3. 我在测试脚本中添加了luasql.postgres库,看看是否有帮助......就像这样:

    package.path = '/var/x/appname/main.lua;'
    
    local pgdb = require("luasql.posgres")
    
    print(pgdb)
    myenv = assert(lua.postgres()) -- fails
    
  4. 测试脚本也试图创建这个对象...我将继续狩猎。它一定是路径的问题......但是我看不出Web应用程序加载时创建的路径与测试脚本中的路径之间的区别。 我现在要使用DIFF工具进行比较。

    任何建议将不胜感激。

    感谢。

    编辑1

    我绝对认为这是路径,虽然我不知道这里有什么问题。 我创建了另一个测试脚本(让我们称之为test3)..但是这一次,我没有通过为package.path分配值来显式设置路径。 我只是尝试包含luasql.postgres pacakge并以原始测试脚本的方式使用它...它的工作原理! 所以这里的代码有效:

    luasql = require "luasql.postgres"
    local myenv = assert (luasql.postgres())
    print(myenv)
    

    但这失败了:

    package.path = package.path .. ';/usr/share/myapp/main.lua'
    
    luasql = require "luasql.postgres"
    myenv = assert (luasql.postgres())
    print(myenv)
    

    对于大狼的观点,我在lua中尝试了交互模式......我的代码工作正常。

    Lua 5.1.5  Copyright (C) 1994-2012 Lua.org, PUC-Rio
    > pgdb = require("luasql.postgres")
    > print(pgdb)
    table: 0x176cb228
    > myenv=assert(luasql.postgres())
    > print(myenv)
    PostgreSQL environment (0x176c9d5c)
    > 
    

    所以......这是交互模式的package.path变量:

    > print(package.path)
    ./?.lua;/usr/local/share/lua/5.1/?.lua;/usr/local/share/lua/5.1/?/init.lua;/usr/local/lib/lua/5.1/?.lua;/usr/local/lib/lua/5.1/?/init.lua;/usr/share/lua/5.1/?.lua;/usr/share/lua/5.1/?/init.lua
    > 
    

    这是我原来的测试脚本失败的路径。

      

    /usr/share/myapp/main.lua; ./?LUA; /usr/local/share/lua/5.1 / ?. LUA; /usr/local/share/lua/5.1 / /初始化。 LUA; /usr/local/lib/lua/5.1 / ?. LUA; /usr/local/lib/lua/5.1 / / init.lua; /usr/share/lua/5.1 / ?. LUA; / USR /共享/ LUA / 5.1 /?/ init.lua

2 个答案:

答案 0 :(得分:4)

这是路径的问题。我仍然不确定到底出了什么问题,但我改变了测试脚本中的逻辑:

package.path = '/usr/share/myapp/main.lua;' -- resetting package path manually
package.path=package.path ..'./?.lua;/usr/local/share/lua/5.1/?.lua;/usr/local/share/lua/5.1/?/init.lua;/usr/local/lib/lua/5.1/?.lua;/usr/local/lib/lua/5.1/?/init.lua;/usr/share/lua/5.1/?.lua;/usr/share/lua/5.1/?/init.lua

package.path = package.path .. '/usr/share/myapp/main.lua' -- append to default path.

现在它找到了lua postgres包,让我也可以调用这些函数

答案 1 :(得分:2)

当Lua执行require "luasql.postgres"时,它会尝试在luasql文件夹中的LUA_PATH文件夹中找到postgres.lua,加载它并执行它,从而放置任何非局部变量(包括函数)出现在全局命名空间中postgres.lua的模块级别。您显示的main.lua需要一个模块,然后将其用作函数:luasql.postgres()。这只有在使用某些技巧时才有效。例如,如果加载的模块返回一个函数,则可以使用

fn = require 'luasql.postgres'
fn()

执行返回的函数。

此外,与python不同,你可以从模块中导入项目,在Lua中你不能。所以它不像postgres可以是一个函数或可调用的表。

如果您使用以下内容替换main.lua

require 'luasql.postgres'
luasql.postgres()

并运行测试脚本,或直接运行main.lua,您应该收到错误消息。如果不这样做,该模块肯定会做一些特殊的事情来支持这种用途。

如果您更改main.lua如上所述并且它不起作用,那么您也无法做到

env = assert (luasql.postgres())

但你可以做任何这些,具体取决于postgres.lua的作用:

env = assert (luasql.postgres)
env = assert (someFunctionDefinedInPostgresModule)
env = assert (someFunctionDefinedInPostgresModule())
env = assert (luasql.postgres.someFunction)
env = assert (luasql.postgres.someFunction())