Module lua模块未加载库 背景资料:
我刚刚接触lua,我正在努力了解模块是如何工作的。但是我正在尝试将一个预先存在的模块加载到一个新脚本中,并从命令行运行这个脚本 代码: 我有一个名为main.lua module的文件,看起来像这样:Module lua模块未加载库 背景资料:,module,lua,Module,Lua,我刚刚接触lua,我正在努力了解模块是如何工作的。但是我正在尝试将一个预先存在的模块加载到一个新脚本中,并从命令行运行这个脚本 代码: 我有一个名为main.lua module的文件,看起来像这样: module (..., package.seeall) -- Load libraries require("luasql.postgres") require("luasql.sqlite3") local connect_to_db = function() if not globa
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())
到目前为止,我所尝试的:
包.path
,以匹配main.lua正在使用的内容。我这样做是通过以“常规”方式执行main.lua(由web应用程序驱动)并将package.path
的内容转储到日志文件中。
我已经从日志文件复制了路径,并将其用作测试脚本中的包.path
值。。。当然,我必须通过添加一个附加条目来修改它—一个指向main.lua的路径。但除此之外,包路径是相同的
package.path = '/var/x/appname/main.lua;'
local pgdb = require("luasql.posgres")
print(pgdb)
myenv = assert(lua.postgres()) -- fails
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)
也是greatwolf的观点,我在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;/?。卢阿/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
当Lua执行
require“luasql.postgres”
时,它会尝试在luasql
文件夹中其Lua\u路径的任何位置查找postgres.Lua,加载并执行它,从而将出现在postgres.Lua
模块级的任何非局部变量(包括函数)放入全局命名空间中。您显示的main.lua
需要一个模块,然后将其用作函数:luasql.postgres()
。这只会在使用某些技巧时起作用。例如,如果加载的模块返回一个函数,您可以使用
fn = require 'luasql.postgres'
fn()
执行返回的函数
此外,与python不同的是,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())
这是一个路径问题。我仍然不确定到底出了什么问题,但我将测试脚本中的逻辑更改为:
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
"
到
现在它找到了lua postgres包,让我也调用函数你能通过lua解释器或repl测试一下,看看luasql.postgres
返回了什么吗?根据postgres
本身应该是一个函数。greatwolf,请查看我的编辑1,被否决的人至少可以发表评论说明原因?我不知道这怎么会不是答案,我很想知道我遗漏了什么。Scholli,我投了反对票,因为你不能称之为luasql.postgres()。这是一个合法的函数调用。如果我误解了你的评论,请让我知道!我很乐意撤销我的否决票!另外,我知道模块只是表……但我对你关于没有“调用”的评论感兴趣。你能再解释一下吗,或者给我指一篇文章来了解更多?谢谢。@dot除非博士后lua正在做一些特别的事情,否则我不认为这是合法的。我已经更新了我的答案,如果你能尝试一下,我会非常感激的。@dot我刚刚看了你的编辑,工作的代码与你在顶部的代码不同:在你的编辑中,你有luasql=require'luasql.postgres',在这种情况下,它当然可以工作,这甚至是我在回答中解释的事情之一。所以我觉得在这里投反对票是不合适的。出于好奇,如果你试着像这样做,package.path='/usr/share/myapp/main.lua;'。。package.path
?经过一些测试,情况变得越来越清楚require
按从左到右的顺序考虑package.path
。对于每个给定的路径,它会检查文件是否存在,如果存在,则会使用该文件,而该模块不考虑其他路径因为它没有?
lua将在需要模块时逐字搜索该文件。我
package.path = package.path .. '/usr/share/myapp/main.lua' -- append to default path.