loadfile()和dostring()在run(wsapi_env)内部无法工作。

我尝试运行以下代码:

#!/usr/bin/env wsapi.cgi

require("lib/request")  -- wsapi lib
require("lib/response")
require("io")
module("loadHtml", package.seeall)

---此函数为需要GET文件的WSAPI调用生成响应
function run(wsapi_env)
    --检查请求
    local req = wsapi.request.new(wsapi_env or {})
    --生成响应
    res = wsapi.response.new()
    ---一些实用函数,用于向响应写入内容
    function print(str) res:write(str) end
    function println(str) res:write(str) res:write('<br/>') end

    println("running...")
    ff=dofile("index.html.lua")
    println("done!")

    return res:finish()
end

return _M

而“index.html.lua”看起来像这样:

print([[<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
</head>
<body>
Hello world!
</html>]])

它可以正常运行,但客户端只会得到这样的内容:

running...<br/>done!<br/>

换句话说,在run()函数中的println()可以正常工作,但在“index.html.lua”内部不起作用。我尝试了loadfile()而不是dofile(),但结果相同。有趣的是,我写了一个测试代码,它可以运行:

- tryDoFileRun.lua:
function e()
    function p(str)
        print(str)
    end
    dofile("tryDoFile.lua")
end
e()

它会运行这个代码:

--tryDoFile.lua
print("in tryDoFile.lua")
p("calling p")

输出是:

in tryDoFile.lua
calling p

与预期一样。但是,这个相同的想法在上面的第一个代码中不起作用。如何使index.html.lua使用我的print()函数?

原文链接 https://stackoverflow.com/questions/7104045

点赞
stackoverflow用户200540
stackoverflow用户200540

问题在于 module 调用。它替换了当前块的环境,但 dofile 没有继承修改后的环境。解决方案要么是直接写入全局环境:

_G.print = function(str) res:write(str) end

要么就是修改加载代码的块的环境:

function print(str) res:write(str) end
ff = loadfile("index.html.lua")
getfenv(ff).print = print
ff()

后者可以包装在一个方便的 HTML 模板加载函数中。

2011-08-18 21:13:49