在 LuaTeX 中定义复数时设置环境

在 LuaTeX 中定义复数时设置环境

我的问题来自于我之前问过的问题。这是代码。

\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.acomplex["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}

现在你的代码可以正常工作了。

在此处输入图片描述

相关内容