![在 LuaTeX 中定义复数时设置环境](https://linux22.com/image/412043/%E5%9C%A8%20LuaTeX%20%E4%B8%AD%E5%AE%9A%E4%B9%89%E5%A4%8D%E6%95%B0%E6%97%B6%E8%AE%BE%E7%BD%AE%E7%8E%AF%E5%A2%83.png)
我的问题来自于这我之前问过的问题。这是代码。
\documentclass{article}
\usepackage{parskip,luacode}
\begin{luacode*}
M = {} -- the module
complex = {} -- global complex numbers registry
local mt = {} --metatable for complex numbers
function new (r, i)
local cp = {}
cp = {r=r, i=i}
return setmetatable(cp,mt)
end
M.new = new -- add 'new' to the module
function M.op (...)
local _ENV = complex
return ...
end
function M.add (c1, c2)
return new(c1.r + c2.r, c1.i + c2.i)
end
function M.tostring (c)
return string.format("(%g,%g)", c.r, c.i) --to avoid +-
end
mt.__tostring = M.tostring
mt.__add = M.add
\end{luacode*}
\newcommand\cpxNew[2]{%
\directlua{%
complex[\luastringN{#1}] = M.new(#2)
}%
}
\newcommand\cpxPrint[1]{%
\directlua{tex.sprint(tostring(complex[\luastringN{#1}]))}%
}
\newcommand\cpxOp[1]{%
\directlua{%
tex.print(tostring(M.op(#1)))
}%
}
\begin{document}
\cpxNew{a}{3,4}
\cpxPrint{a} \par
\cpxOp{complex.a + complex.a} \par
%\cpxOp{a+a}
\end{document}
它被编译了。我也得到了预期的输出,除了注释的最后一个命令\cpxOp{a+a}
。当我取消注释它时,我收到错误(对 nil 值进行算术运算)。我需要这样的东西来设置元表。我期望答案 (6,8)。然而,我得到的是 nil。前一个命令\cpxOp{complex.a +complex.a}
给出了预期的答案。函数有什么问题M.op(...)
。我已经将本地设置_ENV
为复杂,因此我期望获得与\cpxOp{complex.a + complex.a}
命令相同的答案\cpxOp{a+a}
。但这并没有发生。可能是什么原因?任何帮助都将不胜感激。谢谢。
答案1
您的宏\cpxNew
正在表内注册一个元素complex
(在您的例子中为complex.a
或complex["a"]
)。如果您调用a
,您将得到nil
一个未定义的元素。一种解决方法是定义一个新命令,这样您就不必编写complex
编辑
如果您不介意破坏事物,您可以平等complex
和_G
(全局变量)。
%!TEX program = lualatex
\documentclass{standalone}
\usepackage{luacode}
\begin{luacode*}
M = {} -- the module
complex = _G -- global complex numbers registry
local mt = {} --metatable for complex numbers
function new (r, i)
local cp = {}
cp = {r=r, i=i}
return setmetatable(cp,mt)
end
M.new = new -- add 'new' to the module
function M.op (...)
local _ENV = complex
return ...
end
function M.tostring (c)
return string.format("(%g,%g)", c.r, c.i) --to avoid +-
end
mt.__tostring = M.tostring
\end{luacode*}
\newcommand\cpxNew[2]{%
\directlua{%
complex[\luastringN{#1}] = M.new(#2)
}%
}
\newcommand\cpxPrint[1]{%
\directlua{tex.sprint(tostring(complex[\luastring{#1}]))}%
}
\newcommand\cpxOp[1]{%
\directlua{%
tex.print(tostring(M.op(#1)))
}%
}
%Workaround
\newcommand\cpxOpp[1]{%
\directlua{%
tex.print(tostring(M.op(complex[\luastring{#1}])))
}%
}
\begin{document}
\cpxNew{a}{3,4}
\cpxPrint{a}
\cpxOp{a+a}
\end{document}
现在你的代码可以正常工作了。