Lua LaTeX 中为全局环境设置 Metatable 时出错

Lua LaTeX 中为全局环境设置 Metatable 时出错

我有包含以下代码的 set.lua 文件。

local Set = {}   --module      
local mt = {} --metatable
setmetatable(_G,{__index=function(t,k) return k end})  
  --some functions 
  return Set

上面的命令是必需的,因为出于某种原因我想将 lua 表中的条目视为字符串。这是参考https://stackoverflow.com/questions/61107010/how-to-treat-entries-in-lua-table-as-strings# 然后有带有代码的 sty 文件。

\ProvidesPackage{luaset}[2020/04/10]
\RequirePackage{luacode}
\begin{luacode*}
local st = require "set"
--some functions
\end{luacode*}
%some commands
\endinput

该 tex 文件包含以下代码。

\documentclass{article}
\usepackage{luaset}
\begin{document}
abcdefg
\end{document}

一切都按预期进行,除了一个奇怪的事实,即 tex 文件不接受长度大于 7 的单词。这与 lua 文件中的命令无关。它是 tex 文件中的任何单词。例如,如果我在 tex 文件中输入 abcdefgh,它不会被编译,而上述文件会被编译。

答案1

我完全同意 Henri Menke 的观点:

这真是一个糟糕的想法。

甚至链接的 StackOverflow 问题也有来自 DarkWiiPlayer 的评论警告您:

我正要建议同样的事情;请记住,如果它假定未初始化的全局变量为零,那么这种更改可能会破坏其他地方的代码。

甚至比这更糟糕。LuaLaTeX 不假设未初始化的全局变量是nil,但它期望全局变量nil在设置为nil... 之后是(从技术上讲,这在下一次字体加载器导入后不会再中断,因为全局变量的使用是一个错误,将在上游修复,但即使如此,您也不应该这样做,因为它会以类似的方式影响所有其他类型的代码)

无论如何,如果你真的找不到其他方法,您可以限制对您的文件的更改并避免影响其他文件:更改set.lua

local Set = {}   --module      
local mt = {} --metatable
local _ENV = _ENV
local _ENV = setmetatable({}, {
  __index = function(t,k)
    local real_v = _ENV[k]
    if real_v ~= nil then
      return real_v
    end
    return type(k) == 'string' and k:match'^[%w_]+$' and k or nil
  end,
  __newindex = _ENV,
})
--some functions 
return Set

那么只有全局变量出现在 内部时才会被解释为字符串set.lua

相关内容