如何在包含函数

时间:2016-03-21 14:00:03

标签: lua

我正在使用Lua表存储数据来创建网页。正文内容存储在一个表中,有一些静态文本,一些由Lua函数生成。

Web.HTML={
"<h1>Hello World</h1><br>",
"<br><h2>Current Directory</h2><br>",
io.popen("cd"):read('*l'),
"<br><h2>Current Lua Interpreter</h2><br>",
arg[-1] or arg[0],
"<br><h2>Current Package Path</h2><br>",
package.path:gsub(";",";<br>\n"),
"<br><h2>Current Package CPath</h2><br>",
package.cpath:gsub(";",";<br>\n"),
"<br><h2>Current Environment Table:</h2><br>",
io.popen("set"):read('*a'):gsub("\n","<br>\n").." ",
"<br><h2>Current Date:</h2><br>",
os.date(),
"<br><h2>Math calculation</h2><br>",
math.pi/180
}

然后使用table.concat函数“打印”此表,添加一些新行以帮助提高可读性:

print(table.concat(Web.HTML,"<br>\n"))

上面的示例在Lua 5.1或同等版本中按预期工作,服务器成功将其作为我网页的一部分传递。

我想在我的HTML表中放置任意Lua代码,该代码返回一个要连接的字符串,但是我找不到正确的语法。 concat函数在'concat'的表中索引无效值(函数)。

我试过了:

Web.HTML = {
"Classic text example:",
function() print "Hello World"; end,
}

Web.HTML = {
"Classic text example:",
function() return "Hello World"; end,
}

更有用的示例是列出Lua全局环境中的所有表:

Web.HTML = {
    "<br><h2>Current Lua Libraries</h2><br>",
    function()
        local text = ''
        for i,v in pairs(_G) do
            if type(v)=="table" then
               text = text..i.."<br>\n"
            end
        end
        return text
    end
    ,
    "Success!"
}

我也尝试使用loadstring( code ; return text)()作为我表中的条目,但没有成功。欢迎任何指示。

提前致谢。

加文

4 个答案:

答案 0 :(得分:3)

显然,

function返回一个函数。只需使用()立即拨打电话即可。也不要忘记将print更改为return - 您的函数需要返回表的值,而不是将其打印出来!

Web.HTML = {
    "Classic text example:",
    (function() return "Hello World"; end)(),
}

print(table.concat(Web.HTML,"<br>\n"))
-- Classic text example:<br>
-- Hello World

答案 1 :(得分:2)

table.concat不会自动执行遇到的代码。它连接一个字符串(或数字)列表;这是它的工作。如果你传递的东西不是字符串列表,那么你做错了。

如果您有一个字符串列表+ functions-that-return-strings,那么您需要将其转换为字符串列表您自己。这很容易做到:

local list = --However you generate it.
for i, val in ipairs(list) do
  if(type(val) == "function") then
    list[i] = val() --call function
  end
end

然后,您可以将listtable.concat连接起来。如果你想创建表的副本,而不是覆盖现有表,那么这也很容易。

local list = --However you generate it.
local copy = {}
for i, val in ipairs(list) do
  if(type(val) == "function") then
    copy[i] = val() --call function
  else
    copy[i] = val
  end
end

答案 2 :(得分:0)

type将表的元素连接到字符串。因此它是 必须将表中的每个元素都转换为字符串。

在你的所有尝试中:

table.concat

Web.HTML = { "Classic text example:", function() print "Hello World"; end, } 是一个无法转换为字符串的函数。

在这种情况下,你可以用字符串或它们的返回值替换你的函数,只需在列表外定义它们然后在表构造函数中调用它们或者用括号中的函数definitin立即调用它们,或者你可以重载表。满足您的需求。虽然我宁愿实现一个新的concat函数,而不是覆盖标准函数以避免混淆。

答案 3 :(得分:0)

不幸的是,标准函数table.concat()仅适用于字符串和数字。

您可以编写自己更多才多艺的table.concat

do
   local orig_table_concat = table.concat

   -- Define new function "table.concat" which overrides standard one
   function table.concat(list, sep, i, j, ...)
      -- Usual parameters are followed by a list of value converters
      local first_conv_idx, converters, t = 4, {sep, i, j, ...}, {}
      local conv_types = {
         ['function'] = function(cnv, val) return cnv(val)        end,
         table        = function(cnv, val) return cnv[val] or val end
      }
      if conv_types[type(sep)]   then first_conv_idx, sep, i, j = 1
      elseif conv_types[type(i)] then first_conv_idx,      i, j = 2
      elseif conv_types[type(j)] then first_conv_idx,         j = 3
      end
      sep, i, j = sep or '', i or 1, j or #list
      for k = i, j do
         local v, idx = list[k], first_conv_idx
         while conv_types[type(converters[idx])] do
            v = conv_types[type(converters[idx])](converters[idx], v)
            idx = idx + 1
         end
         t[k] = tostring(v) -- 'tostring' is always the final converter
      end
      return orig_table_concat(t, sep, i, j)
   end
end

用法示例:

Web = {}
Web.HTML = {
   "Classic text example:",
   function() return "Hello World"; end,
}

-- without converters
print(table.concat(Web.HTML, "<br>\n"))
--> Classic text example:<br>
--> function: 0x9ad1398

-- with a converter
print(table.concat(
   -- usual parameters for table.concat:
   Web.HTML, "<br>\n",
   -- additional parameters (converters):
   function(x)
      if type(x) == 'function' then
         return x()
      else
         return x
      end
   end
))
--> Classic text example:<br>
--> Hello World