LuaTeX: melhores práticas de codificação da lua

Nov 17 2020

Quais são algumas das melhores práticas de codificação a serem seguidas ao dividir e carregar o código lua de vários arquivos lua externos e ao lidar com o código lua de outros pacotes lualatex. Esse pensamento vem à mente, pois agora tenho um monte de arquivos lua que posso carregar e usar, mas não é o código mais bem dividido. Algumas perguntas feitas como "observação" aqui são repetidas abaixo com mais clareza (e acréscimos):

  1. Quanto ao escopo, e possível conflito de nomes de "variáveis ​​locais" em arquivos lua externos: No arquivo linebreak.lua desta questão , qual é o escopo das variáveis ​​locais local n, head, last? Se eu carregar outro arquivo lua com "require", e que tenha variáveis ​​locais com nomes semelhantes, isso seria um problema? Lua mantém variáveis ​​locais locais para as funções no arquivo de onde está sendo carregada? (mesmo que eu apenas os carregue no namespace global)

  2. Qual é a prática recomendada para evitar que variáveis ​​e funções em um arquivo entrem em conflito / substituam / interfiram com as de outro arquivo?

  3. É parte das diretrizes de documentação dos desenvolvedores do pacote lualatex documentar o que eles estão adicionando ao namespace global? No caso de um pacote lualatex escrever um nome para o namespace global e entrar em conflito com meu nome de variável / função, qual é o melhor lugar para começar a depuração?

  4. Qual é o escopo entre dois blocos directlua / latelua diferentes? Em minha observação, as variáveis ​​locais são locais para blocos directlua, e acabei usando o namespace global no passado para "passar" valores de um bloco directlua para outro. Existe uma maneira mais limpa que evita o uso de namespace global?

Respostas

3 JosephWright Nov 17 2020 at 11:18

As variáveis ​​Lua são locais para a função ou escopo em que são definidas. Arquivos de origem separados constituem escopos, portanto, cada um require()significa que as variáveis ​​são locais para aquele arquivo. Isso também é verdadeiro para \directluachamadas, mas além de aplicativos triviais, você deve carregar o código Lua usando uma única \directlua{require("myfile")}linha. Eu acho que mais detalhes sobre o que você está fazendo são necessários para comentar mais sobre 'passagem de informações entre \directlualigações'.

Normalmente, a melhor maneira de lidar com globais é declarar uma única tabela e ter todo o material global nela. Existem algumas maneiras, mas por exemplo:

foo = foo or { }
foo.my_func = function(...)
end

ou

foo = foo or { }
local function my_func(...)
end
foo.my_func = foo.my_func or my_func

Se desejar, você pode incluir um teste de segurança para a tabela global

if foo then
  print("Oh no, someone has taken my table")
  os.exit(1)
end

Não há documentação / sistema formal para lidar com o namespace global. Eu sugiro que você siga a mesma abordagem usada para macros TeX: escolha um nome sensato com base no nome do seu pacote.