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.

local st = require "set"
--some functions
%some commands

The tex file has the following code.


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.

  • 2
    This is a really bad idea. Apr 9, 2020 at 8:16
  • Also can't reproduce. Apr 9, 2020 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, 2020 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) Apr 9, 2020 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, 2020 at 16:31

1 Answer 1


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
    return type(k) == 'string' and k:match'^[%w_]+$' and k or nil
  __newindex = _ENV,
--some functions 
return Set

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .