第一版是为 Lua 5.0 编写的。虽然在很大程度上仍然适用于后续版本,但有一些差异。
第四版针对 Lua 5.3,可在 亚马逊 和其他书店购买。
购买本书,您还可以支持 Lua 项目。
![]() |
用 Lua 编程 | ![]() |
| 第一部分。语言 第 10 章。完整示例 |
Lua 网站保留了一个数据库,其中包含使用 Lua 的全球项目示例。我们以自动记录的方式通过构造函数在数据库中表示每个条目,如下例所示
entry{
title = "Tecgraf",
org = "Computer Graphics Technology Group, PUC-Rio",
url = "http://www.tecgraf.puc-rio.br/",
contact = "Waldemar Celes",
description = [[
TeCGraf is the result of a partnership between PUC-Rio,
the Pontifical Catholic University of Rio de Janeiro,
and <A HREF="http://www.petrobras.com.br/">PETROBRAS</A>,
the Brazilian Oil Company.
TeCGraf is Lua's birthplace,
and the language has been used there since 1993.
Currently, more than thirty programmers in TeCGraf use
Lua regularly; they have written more than two hundred
thousand lines of code, distributed among dozens of
final products.]]
}
这种表示的有趣之处在于,包含此类条目序列的文件是一个 Lua 程序,它使用表作为调用参数对函数 entry 进行一系列调用。
我们的目标是编写一个程序,以 HTML 格式显示该数据,以便它成为网页 https://lua.ac.cn/uses.html。由于有许多项目,最终页面首先显示所有项目标题的列表,然后显示每个项目的详细信息。程序的结果类似于这样
<HTML>
<HEAD><TITLE>Projects using Lua</TITLE></HEAD>
<BODY BGCOLOR="#FFFFFF">
Here are brief descriptions of some projects around the
world that use <A HREF="home.html">Lua</A>.
<BR>
<UL>
<LI><A HREF="#1">TeCGraf</A>
<LI> ...
</UL>
<H3>
<A NAME="1" HREF="http://www.tecgraf.puc-rio.br/">TeCGraf</A>
<BR>
<SMALL><EM>Computer Graphics Technology Group,
PUC-Rio</EM></SMALL>
</H3>
TeCGraf is the result of a partnership between
...
distributed among dozens of final products.<P>
Contact: Waldemar Celes
<A NAME="2"></A><HR>
...
</BODY></HTML>
为了读取数据,程序所要做的就是为 entry 提供一个适当的定义,然后将数据文件作为程序运行(使用 dofile)。请注意,我们必须遍历所有条目两次,第一次是用于标题列表,第二次是用于项目描述。一种最初的方法是将所有条目收集到一个数组中。但是,由于 Lua 编译得非常快,因此还有一种有吸引力的解决方案:运行数据文件两次,每次都使用不同的 entry 定义。我们在下一个程序中遵循此方法。
首先,我们定义一个用于编写格式化文本的辅助函数(我们已经在 第 5.2 节 中看到了此函数)
function fwrite (fmt, ...)
return io.write(string.format(fmt, unpack(arg)))
end
BEGIN 函数只是编写页面标题,该标题始终相同
function BEGIN()
io.write([[
<HTML>
<HEAD><TITLE>Projects using Lua</TITLE></HEAD>
<BODY BGCOLOR="#FFFFFF">
Here are brief descriptions of some projects around the
world that use <A HREF="home.html">Lua</A>.
<BR>
]])
end
entry 的第一个定义将每个标题项目写为列表项。参数 o 将是描述项目的表
function entry0 (o)
N=N + 1
local title = o.title or '(no title)'
fwrite('<LI><A HREF="#%d">%s</A>\n', N, title)
end
如果 o.title 为 nil(即未提供该字段),则该函数使用固定字符串 "(no title)"。
第二个定义编写有关项目的全部有用数据。它稍微复杂一些,因为所有项目都是可选的。
function entry1 (o)
N=N + 1
local title = o.title or o.org or 'org'
fwrite('<HR>\n<H3>\n')
local href = ''
if o.url then
href = string.format(' HREF="%s"', o.url)
end
fwrite('<A NAME="%d"%s>%s</A>\n', N, href, title)
if o.title and o.org then
fwrite('<BR>\n<SMALL><EM>%s</EM></SMALL>', o.org)
end
fwrite('\n</H3>\n')
if o.description then
fwrite('%s', string.gsub(o.description,
'\n\n\n*', '<P>\n'))
fwrite('<P>\n')
end
if o.email then
fwrite('Contact: <A HREF="mailto:%s">%s</A>\n',
o.email, o.contact or o.email)
elseif o.contact then
fwrite('Contact: %s\n', o.contact)
end
end
(为了避免与使用双引号的 HTML 发生冲突,我们在本程序中只使用单引号。)最后一个函数关闭页面
function END()
fwrite('</BODY></HTML>\n')
end
最后,主程序启动页面,使用 entry(entry0)的第一个定义运行数据文件以创建标题列表,然后使用 entry 的第二个定义再次运行数据文件,并关闭页面
BEGIN()
N = 0
entry = entry0
fwrite('<UL>\n')
dofile('db.lua')
fwrite('</UL>\n')
N = 0
entry = entry1
dofile('db.lua')
END()
| 版权所有 © 2003–2004 Roberto Ierusalimschy。保留所有权利。 | ![]() |