# Error when Metatable is set for global environment in Lua LaTeX

I have the set.lua file with the following code.

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


The above command is required as I want to treat entries in lua table as strings for some reason. Here is the reference https://stackoverflow.com/questions/61107010/how-to-treat-entries-in-lua-table-as-strings# Then there is sty file with the code.

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


The tex file has the following code.

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


Everything works as expected except for one strange fact that tex file is not accepting words of length greater than 7. It has nothing to do with commands in lua file. It is any word in tex file. For example if I type abcdefgh in tex file it doesn't get compiled, whereas the above file gets compiled.

• This is a really bad idea. – Henri Menke Apr 9 '20 at 8:16
• Also can't reproduce. – Henri Menke Apr 9 '20 at 8:21
• It may be bad idea but may be it is required specially when dealing with only strings. No need to declare strings into quotes. Also there should be no problem in reproducing the code. With the proper names set.lua, luaset.sty and test.tex, it should get compiled with luatex. – user61681 Apr 9 '20 at 9:35
• I'm using TeX Live 2020 pretest and I can't reproduce. Here is the log: dpaste.com/0ZE85TC (expires in 10 days) – Henri Menke Apr 9 '20 at 9:39
• Okay. Though it works with LuaTex (earlier engine) and also on sharelatex platform. You are correct. I need to find other way of doing this. – user61681 Apr 9 '20 at 16:31

I fully agree with Henri Menke:

This is a really bad idea.

Even the linked StackOverflow question has a comment from DarkWiiPlayer warning you:

I was about to suggest the same thing; just keep in mind that this change could break code elsewhere if it assumes uninitialized globals to be nil.

It's even worse than that. LuaLaTeX doesn't assume uninitialized globals to be nil, but it expects globals to be nil after they are set to nil... (Technically this will no longer break after the next fontloader import because the use of the global variable is a bug which will be fixe upstream, but even then you really shouldn't do this because it can affect all kinds of other code similarly)

Anyway, if you really can't find another way, you can restrict the change to your file and avoid affecting other files: Change set.lua to

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


Then globals will only be interpreted as string if they appear inside of set.lua.