接下来的代码来自《LUA 编程第四版》。图 20.1。集合的简单模块(元表和元方法部分)这里我仅使用函数 Set.new 的第二个代码
更确切地说,书中给出的代码是纯粹作为 lua 理解的部分。我的问题在于让它与 lualatex 一起工作,并了解我需要做哪些更改。
\documentclass{article}
\usepackage{luacode}
\begin{document}
\parindent=0pt
\LuaCodeDebugOn
\luadirect{
local Set = {}
local mt = {}
function Set.new (l)
local set = {}
setmetatable(set, mt)
for _, v in ipairs(l) do set[v] = true end
return set
end
function Set.union (a, b)
local res = Set.new{}
for k in pairs(a) do res[k] = true end
for k in pairs(b) do res[k] = true end
return res
end
function Set.intersection (a, b)
local res = Set.new{}
for k in pairs(a) do
res[k] = b[k]
end
return res
end
function Set.tostring (set)
local l = {}
for e in pairs(set) do
l[#l + 1] = tostring(e)
end
return "{" .. table.concat(l, ", ") .. "}"
end
return Set
s1 = Set.new{10, 20, 30, 50}
s2 = Set.new{30, 1}
mt.__add = Set.union
s3 = s1 + s2
print(Set.tostring(s3))
% mt.__mul = Set.intersection
% print(Set.tostring((s1 + s2)*s1))
}
\end{document}
在此代码中我当然尝试修改Set.tostring
和使用tex.sprint
但在所有情况下我只看到nil
结果。
我也不明白的是return Set
后面的内容function Set.tostring (set)
,我必须承认元表的使用相当混乱。有多少个例子,就有多少个方法。
问题是:如何转换此代码至少以使其正确执行,以及更一般地讲,处理元表的正确方法是什么。
备注:ctan 的代码luaset.sty
基于我提供的代码,但它带来了其他的复杂性,尤其是它没有帮助我理解。
答案1
最好将较大的 Lua 块放在文件中,以避免与 TeX catcodes 发生冲突。
set.lua
local Set = {}
local mt = {}
function Set.new (l)
local set = {}
setmetatable(set, mt)
for _, v in ipairs(l) do set[v] = true end
return set
end
function Set.union (a, b)
local res = Set.new{}
for k in pairs(a) do res[k] = true end
for k in pairs(b) do res[k] = true end
return res
end
function Set.intersection (a, b)
local res = Set.new{}
for k in pairs(a) do
res[k] = b[k]
end
return res
end
function Set.tostring (set)
local l = {}
for e in pairs(set) do
l[#l + 1] = tostring(e)
end
return "{" .. table.concat(l, ", ") .. "}"
end
mt.__add = Set.union
mt.__mul = Set.intersection
return Set
然后您就可以使用\directlua
它来进行调用(我通常不使用luacode
包装器)
\documentclass{article}
\begin{document}
\parindent=0pt
\directlua{Set=require('set')}
\typeout{=====}
\directlua{
s1 = Set.new{10, 20, 30, 50}
s2 = Set.new{30, 1}
s3 = s1 + s2
print(Set.tostring(s3))
print(Set.tostring(s1*s2))
print(Set.tostring((s1 + s2)*s1))
}
\typeout{=====}
\end{document}
生成:
=====
{1, 20, 30, 10, 50}
{30}
{20, 50, 30, 10}
=====