Helpers
Helpers são um conjunto de funções auxiliares Lua para trabalho confortável no projeto.
Essas funções helper estendem significativamente as capacidades padrão do Lua e simplificam o desenvolvimento.
String
Métodos fornecidos pelo Luanti:
string:lower()
Converte string para minúsculas com suporte para cirílico.
print(('ПРИВЕТ МИР'):lower()) -- 'привет мир'string:upper()
Converte string para maiúsculas com suporte para cirílico.
print(string.upper('привет мир')) -- 'ПРИВЕТ МИР'string:is_one_of(table)
Verifica se o string é um dos valores no array passado.
(Análogo semântico de table.contains, que verifica se o string está contido no array passado.)
local text = 'hello'
local options = { 'hello', 'world', 'lua' }
print(text:is_one_of(options)) -- truestring:first_to_upper()
Converte a primeira letra para maiúscula.
local text = 'hello world'
print(text:first_to_upper()) -- 'Hello world'string :title()/:to_headline()
Converte a primeira letra de cada palavra para title case.
Nome alternativo: string:to_headline()
local text = 'hello world from lua'
print(text:title()) -- 'Hello World From Lua'
print(text:to_headline()) -- 'Hello World From Lua'string:starts_with(prefix)
Verifica se o string começa com o prefixo especificado.
local filename = 'config.json'
print(filename:starts_with('config')) -- true
print(filename:starts_with('settings')) -- falsestring:ends_with(suffix)
Verifica se o string termina com o sufixo especificado.
local filename = 'config.json'
print(filename:ends_with('.json')) -- true
print(filename:ends_with('.conf')) -- falsestring:contains(sub_string)
Verifica a presença de uma substring.
local text = 'Hello, World !!!'
print(text:contains('World')) -- true
print(text:contains('world')) -- false (sensível a maiúsculas/minúsculas)string:replace(pattern, replacement, n?)
Substitui substring (análogo de gsub, mas retorna apenas o string sem o número de substituições).
Veja documentação para string.gsub e Patterns
local text = 'Hello, World, World!'
local result = text:replace('World', 'Lua')
print(result) -- 'Hello, Lua, Lua!'
-- Substituir apenas a primeira ocorrência
local result2 = text:replace('World', 'Lua', 1)
print(result2) -- 'Hello, Lua, World!'string:remove(pattern, n?)
Remove substring.
Veja documentação para string.gsub e Patterns
local text = 'Hello, World!'
print(text:remove(', ')) -- 'HelloWorld!'
print(text:remove('o', 1)) -- 'Hell, Wrld!' (remove apenas o primeiro 'o')string:reg_escape()
Escapa caracteres especiais para expressões regulares.
Veja Patterns
local pattern = 'file.txt'
print(pattern:reg_escape()) -- 'file%.txt'
local pattern2 = '^$()%.[]*+-?)'
print(pattern2:reg_escape()) -- '%^%$()%.%[%]%*%+\-%?)'string:vxr_split(delimiter?, processor?)
Divide string pelo delimiter especificado com capacidade de processar partes.
Luanti tem seu próprio método string.split, mas não suporta processamento de partes.
Este método adiciona a capacidade de processar partes do string.
-- Sem processamento
('hello world'):vxr_split() -- { 'hello', 'world' }
('apple,banana,cherry'):vxr_split(',') -- { 'apple', 'banana', 'cherry' }
-- Com processamento
local numbers = '1,2,3,4,5'
local squared = numbers:vxr_split(',', function(x)
return tonumber(x)^2
end)
print(squared[1], squared[2], squared[3], squared[4], squared[5])
-- 1 4 9 16 25string.or_nil(value)
Converte para string ou retorna nil.
print(string.or_nil('hello')) -- 'hello'
print(string.or_nil(42)) -- '42'
print(string.or_nil(nil)) -- nil
print(tostring(nil)) -- 'nil' (comparação)Métodos fornecidos pelo Luanti:
Luanti string.split()
Veja também: string.vxr_split(delimiter?, processor?)
Divide string em partes pelo separador especificado. Retorna array de strings. Argumentos:
separator?separador, padrão:","include_empty?padrão:falsemax_splits?se negativo, divisões ilimitadas, padrão:-1sep_is_pattern?se separador é string regular ou pattern (regex), padrão:false
local text = 'apple,banana,cherry'
local parts = text.split(',')
print(parts[1], parts[2], parts[3]) -- 'apple', 'banana', 'cherry'
-- Dividir por espaços
local words = 'hello world lua'.split(' ')
print(words[1], words[2], words[3]) -- 'hello', 'world', 'lua'Luanti string.trim()
Remove caracteres de espaço em branco no início e fim do string.
print(("\n \t\tfoo bar\t "):trim()) -- 'foo bar'Luanti string.pack()
Empacota valores em string binário de acordo com o formato.
Backport do Lua 5.4.
-- Empacotar inteiros
local packed = string.pack('i4', 42)
print(#packed) -- 4 (tamanho em bytes)
-- Empacotar múltiplos valores
local data = string.pack('i4f8', 100, 3.14)
print(#data) -- 12 (4 + 8 bytes)Luanti string.unpack()
Desempacota string binário em valores de acordo com o formato.
Backport do Lua 5.4.
local packed = string.pack('i4f8', 100, 3.14)
local num, float, next_pos = string.unpack('i4f8', packed)
print(num, float) -- 100, 3.14
print(next_pos) -- 13 (posição após desempacotar)
-- Desempacotar da posição especificada
local value = string.unpack('i4', packed, 5)
print(value) -- 3.14 (como float)Luanti string.packsize()
Retorna o tamanho do string que será criado por string.pack.
Backport do Lua 5.4.
local size = string.packsize('i4f8')
print(size) -- 12 (4 + 8 bytes)
-- Para formatos complexos
local complex_size = string.packsize('i4c10f8')
print(complex_size) -- 22 (4 + 10 + 8 bytes)Table
Métodos, fornecidos pelo Luanti:
table.copy()table.copy_with_metatables()table.insert_all()
table.indexof()table.keyof()table.key_value_swap()table.shuffle()
table.keys(table)
Retorna um array de chaves da tabela.
local data = { name = 'Alek', age = 25, city = 'Vladivostok' }
local keys = table.keys(data)
-- `keys` contém `{ 'name', 'age', 'city' }` (ordem pode variar)table.values(table)
Retorna um array de valores da tabela.
local data = { name = 'Alek', age = 25, city = 'Vladivostok' }
local values = table.values(data)
-- `values` contém { 'Alek', 25, 'Vladivostok' }table.has_key(table, key)
Verifica se uma chave existe na tabela.
local data = { name = 'Alek', age = 25 }
print(table.has_key(data, 'name')) -- true
print(table.has_key(data, 'city')) -- falsetable .contains/has_value(table, value)
Verifica se um valor existe na tabela.
local fruits = { 'apple', 'banana', 'cherry' }
print(table.contains(fruits, 'banana')) -- true
print(table.contains(fruits, 'orange')) -- falseVocê também pode usar string:is_one_of():
print('banana':is_one_of(fruits)) -- true
print('orange':is_one_of(fruits)) -- falseNome alternativo: table.has_value
local data = { x = 10, y = 20 }
print(table.has_value(data, 10)) -- true
print(table.has_value(data, 30)) -- falsetable.keys_of(table, value)
Retorna uma tabela com chaves da tabela especificada que têm o valor especificado.
local data = { a = 10, b = 20, c = 10, d = 30 }
local keys = table.keys_of(data, 10)
print(dump(keys)) -- { 'a', 'c' }
local keys2 = table.keys_of(data, 99)
print(keys2) -- nil (nenhuma chave assim)table.has_any_key(table, find_keys)
Verifica se as chaves da tabela contêm pelo menos um valor do array especificado.
local data = { name = 'test', age = 25, active = true }
local find_keys = { 'name', 'email', 'phone' }
print(table.has_any_key(data, find_keys)) -- true (chave 'name' está em find_keys)
local find_keys2 = { 'email', 'phone', 'address' }
print(table.has_any_key(data, find_keys2)) -- falsetable.equals(table1, table2)
Compara recursivamente duas tabelas para igualdade completa.
local table1 = { a = 1, b = { c = 2, d = 3 } }
local table2 = { a = 1, b = { c = 2, d = 3 } }
local table3 = { a = 1, b = { c = 2, d = 4 } }
print(table.equals(table1, table2)) -- true
print(table.equals(table1, table3)) -- falsetable.is_empty(table)
Verifica se a tabela está vazia.
print(table.is_empty({})) -- true
print(table.is_empty({ a = 1 })) -- falsetable.is_position(table)
Verifica se a tabela representa coordenadas.
print(table.is_position({ x = 10, y = 20, z = 30 })) -- true
print(table.is_position({ x = 10, y = 20 })) -- false
print(table.is_position({ a = 1, b = 2, c = 3 })) -- falsetable.each_value_is(table, value)
Verifica que todos os elementos da tabela são iguais ao valor especificado. Por padrão verifica para true.
local data1 = { true, true, true }
print(table.each_value_is(data1)) -- true
local data2 = { 5, 5, 5, 5 }
print(table.each_value_is(data2, 5)) -- true
local data3 = { 1, 2, 3 }
print(table.each_value_is(data3, 1)) -- falsetable.count(table)
Conta o número de elementos na tabela.
NOTE
Para tabelas com chaves inteiras, use #table.
Como o operador # não funciona em tabelas com chaves não-inteiras, use table.count para elas.
local data = { a = 1, b = 2, c = 3 }
print(table.count(data)) -- 3
print(#data) -- 0, porque o operador `#` não funciona com chaves não-inteiras.
local array = { 1, 2, 3, 4, 5 }
print(#array) -- 5table.generate_sequence(max, start_from?, step?)
Gera uma sequência de números.
local seq1 = table.generate_sequence(5)
print(dump(seq1)) -- { 1, 2, 3, 4, 5 }
local seq2 = table.generate_sequence(10, 2, 2)
print(dump(seq2)) -- { 2, 4, 6, 8, 10 }
local seq3 = table.generate_sequence(1, 5, -1)
print(dump(seq3)) -- { 5, 4, 3, 2, 1 }table.only(table, only)
Retorna uma nova tabela contendo dados apenas com as chaves especificadas.
local data = { name = 'Alek', age = 25, city = 'Vladivostok', country = 'Russia' }
local filtered = table.only(data, { 'name', 'age' })
-- `filtered` contém `{ name = 'Alek', age = 25 }`
print(filtered.name, filtered.age) -- 'Alek', 25
print(filtered.city) -- niltable.except(table, keys)
Retorna uma nova tabela contendo dados sem as chaves especificadas.
(copia a tabela, excluindo as chaves especificadas)
local data = { name = 'Alek', age = 25, city = 'Vladivostok', country = 'Russia' }
local filtered = table.except(data, { 'age', 'country' })
-- `filtered` contém `{ name = 'Alek', city = 'Vladivostok' }`
print(filtered.name, filtered.city) -- 'Alek', 'Vladivostok'
print(filtered.age, filtered.country) -- nil, niltable.merge(table1, table2, overwrite?)
Mescla tabelas recursivamente.
Por padrão, a primeira tabela não é sobrescrita, uma nova é criada.
local defaults = { theme = 'dark', font = { size = 12, family = 'Arial' } }
local user_config = { font = { size = 16 }, language = 'en' }
local merged = table.merge(defaults, user_config)
print(dump(merged))
-- {
-- theme = "dark",
-- font = {
-- size = 16,
-- family = "Arial",
-- },
-- language = "en",
-- }Sobrescrever a primeira tabela:
table.merge(defaults, user_config, true)TIP
É melhor usar table.overwrite() para melhor legibilidade.
table.join(table1, table2, recursively?)
Adiciona chaves ausentes de table2 a table1.
Valores que são tabelas são copiados usando table.copy().
local base = { a = 1, b = 2 }
local addition = { b = 10, c = 3 }
table.join(base, addition)
print(dump(base)) -- { a = 1, b = 2, c = 3 }Se recursively for true, a função será aplicada recursivamente apenas para valores que são tabelas em ambos table1 e table2.
local base = { a = 1, b = { c = 2 } }
local addition = { b = { c = 10, d = 20 } }
table.join(base, addition, true)
print(dump(base))
-- {
-- a = 1,
-- b = {
-- c = 2,
-- d = 20,
-- },
-- }table.overwrite(table1, table2)
Sobrescreve completamente table1 com valores de table2.
Variante semântica para table.merge(table1, table2, true).
table.merge_values(table1, table2)
Mescla valores de duas tabelas em uma, removendo duplicatas.
Ordem é preservada - primeiro valores de table1, depois de table2 que não estavam em table1.
local table1 = { 'apple', 'banana', 'cherry' }
local table2 = { 'banana', 'date', 'apple', 'elderberry' }
local merged = table.merge_values(table1, table2)
print(dump(merged)) -- { 'apple', 'banana', 'cherry', 'date', 'elderberry' }table.map(table, callback, overwrite?)
Aplica função a cada elemento da tabela.callback: fun(value: any, key: any): any - aceita valor e chave, retorna novo valor.
Por padrão retorna uma nova tabela.
local numbers = { 1, 2, 3, 4, 5 }
local squared = table.map(numbers, function(x) return x * x end)
print(dump(squared))
-- { 1, 4, 9, 16, 25 }
local data = { a = 10, b = 20 }
local doubled = table.map(data, function(value, key)
print(key, value)
return value * 2
end)
-- a 10
-- b 20
print(dump(doubled))
-- { a = 20, b = 40 }Se overwrite for true, então a função modifica a tabela original.
local data = { a = 10, b = 20 }
table.map(data, function(value, key) return value * 2 end, true)
print(dump(data)) -- { a = 20, b = 40 }table .walk/.each(table, callback)
Itera sobre a tabela aplicando função (não modifica a tabela).callback: fun(value: any, key: any): void - aceita valor e chave; não retorna nada.
local data = { a = 10, b = 20, c = 30 }
table.walk(data, function(value, key)
print(key, value)
end)
-- a 10
-- c 30
-- b 20Nome alternativo: table.each()
local data = { a = 10, b = 20, c = 30 }
table.each(data, function(value, key)
data[key] = value * 2
-- Nada impede o acesso à upvalue `data`. Agora `data` foi sobrescrito.
end)
print(dump(data)) -- { a = 20, b = 40, c = 60 }table.multiply_each_value(table, multiplier_table)
Multiplica cada valor da tabela pelo valor correspondente de multiplier_table por chave.
local data = { a = 10, b = 20, c = 30 }
local multipliers = { a = 2, b = 0.5, c = 3 }
local result = table.multiply_each_value(data, multipliers)
print(dump(result)) -- { a = 20, b = 10, c = 90 }
-- Chaves sem multiplicador permanecem inalteradastable.add_values(table1, table2, empty_value?, overwrite?)
Adiciona valores com as mesmas chaves de duas tabelas.
local table1 = { a = 10, b = 20 }
local table2 = { b = 5, c = 15 }
local result = table.add_values(table1, table2)
print(dump(result)) -- { a = 10, b = 25, c = 15 }
-- Com valor vazio para chaves ausentes
local result2 = table.add_values(table1, table2, 0)
print(dump(result2)) -- { a = 10, b = 25, c = 15 }table.sub_values(table1, table2, empty_value?, overwrite?)
Subtrai valores table2 de table1 para chaves iguais.
local table1 = { a = 10, b = 20, c = 30 }
local table2 = { b = 5, c = 10, d = 5 }
local result = table.sub_values(table1, table2)
print(dump(result)) -- { a = 10, b = 15, c = 20, d = -5 }table.mul_values(table1, table2, empty_value?, overwrite?)
Multiplica valores com as mesmas chaves de duas tabelas.
local table1 = { a = 2, b = 3 }
local table2 = { b = 4, c = 5 }
local result = table.mul_values(table1, table2)
print(dump(result)) -- { a = 2, b = 12, c = 5 }table.div_values(table1, table2, empty_value?, overwrite?)
Divide valores table1 pelos valores table2 para chaves iguais.
local table1 = { a = 10, b = 20, c = 30 }
local table2 = { b = 5, c = 10, d = 2 }
local result = table.div_values(table1, table2)
print(dump(result)) -- { a = 10, b = 4, c = 3, d = 0.5 }Math
math .limit/.clamp(value, min, max)
Limita valor ao intervalo especificado.
Nome alternativo: math.clamp().
local health = 150
local max_health = 100
local clamped_health = math.limit(health, 0, max_health)
print(clamped_health) -- 100math.is_within(value, min, max)
Verifica que o valor está estritamente dentro do intervalo (min < value < max).
print(math.is_within(5, 1, 10)) -- true
print(math.is_within(1, 1, 10)) -- false (limites não incluídos)
print(math.is_within(10, 1, 10)) -- falsemath.is_among(value, min, max)
Verifica que o valor está dentro do intervalo, incluindo limites (min <= value <= max).
print(math.is_among(5, 1, 10)) -- true
print(math.is_among(1, 1, 10)) -- true
print(math.is_among(10, 1, 10)) -- truemath.is_in_range(value, min, max)
Verifica que o valor está dentro do intervalo semiaberto (min, max] (min < value <= max).
print(math.is_in_range(5, 1, 10)) -- true
print(math.is_in_range(1, 1, 10)) -- false (igual ao mínimo)
print(math.is_in_range(10, 1, 10)) -- true (igual ao máximo)math.is_near(value, near, gap?)
Verifica que o valor está próximo do especificado (|value - near| <= gap).
print(math.is_near(10, 12)) -- false (gap = 1 por padrão)
print(math.is_near(11, 12)) -- true
print(math.is_near(10, 12, 3)) -- true (gap = 3)math.quadratic_equation_roots(a, b, c)
Resolve equação quadrática da forma y = a*x^2 + b*x + c.
local root1, root2 = math.quadratic_equation_roots(1, -5, 6)
print(root1, root2) -- 3, 2
-- Sem raízes reais
local r1, r2 = math.quadratic_equation_roots(1, 0, 1)
print(r1, r2) -- nil, nilmath.point_on_circle(radius, angle)
Calcula um ponto em um círculo.
local x, z = math.point_on_circle(5, math.pi/4)
print(x, z) -- coordenadas de um ponto em um círculo com raio 5 no ângulo 45°Debug
__FILE__(depth?, full?)
Retorna o nome do arquivo atual ou do arquivo da função chamadora dependendo da profundidade da pilha.
depth?- profundidade da pilha de chamadas (padrão0)full?- mostrar caminho completo (padrãofalse)
-- Obter caminho relativo do arquivo
print(__FILE__()) -- 'mods/Voxrame/helpers/src/lua_ext/debug.lua'
-- Obter caminho completo do arquivo
print(__FILE__(0, true)) -- '/home/alek13/projects/my-game/mods/Voxrame/helpers/src/lua_ext/debug.lua'
-- Obter arquivo 2 níveis acima na pilha de chamadas
print(__FILE__(2)) -- arquivo da função que chamou a função chamadora__LINE__(depth?)
Retorna o número da linha atual ou da linha da função chamadora dependendo da profundidade da pilha.
print(__LINE__()) -- 57
-- Obter número da linha da função chamadora
print(__LINE__(1)) -- número da linha no arquivo de chamada__FILE_LINE__(depth?, full?)
Retorna arquivo e linha no formato "caminho/relativo/para/arquivo:linha".
print(__FILE_LINE__()) -- 'mods/Voxrame/helpers/src/lua_ext/debug.lua:65'
-- Com caminho completo
print(__FILE_LINE__(0, true)) -- '/home/alek13/projects/my-game/mods/Voxrame/helpers/src/lua_ext/debug.lua:65'__DIR__(depth?)
Retorna o diretório do arquivo atual ou do arquivo da função chamadora dependendo da profundidade da pilha.
print(__DIR__()) -- 'mods/Voxrame/helpers/src/lua_ext/'__FUNC__(depth?)
Retorna o nome da função atual.
function my_function()
print(__FUNC__()) -- 'my_function'
endprint_dump(depth, with_trace, ...)
Produz o conteúdo de todos os parâmetros passados ....
Antes da saída, adiciona nome do arquivo e linha @ <file>:<line>.
Se with_trace for true, adicionalmente produz stack trace.
NOTE
Se seu terminal suporta links, cada @ <file>:<line> será vinculado à abertura da IDE, veja readme.md para configuração.
TIP
Use pd() e pdt() para sintaxe mais concisa. Veja exemplos abaixo.
pd(...)
Abreviação para print_dump. Chama print_dump com with_trace == false.
local player_name = 'test_player'
local position = { x = 10, y = 20, z = 30 }
pd(player_name, position)output:
[93m@ [0m[33mmods/lord/Core/map/src/map/Corridor.lua[0m[97m:[0m[32m14[0m
[36mplayer_name:[0m "test_player"
[36m position:[0m {
x = 10,
y = 20,
z = 30,
}pdt(...)
Abreviação para print_dump traced. Chama print_dump com with_trace == true.
local player_name = 'test_player'
local position = { x = 10, y = 20, z = 30 }
pdt(player_name, position)output:
[93m@ [0m[33mmods/lord/Core/map/src/map/Corridor.lua[0m[97m:[0m[32m14[0m
[3m[2m 1 [0m[93m@[0m [C][36m: in dofile[0m
[3m[2m 2 [0m[93m@ [0m[33mmods/lord/Core/builtin_ext/src/mod/require.lua[0m[97m:[0m[32m29[0m[36m: in require[0m
[3m[2m 3 [0m[93m@ [0m[33mmods/lord/Core/map/src/map.lua[0m[97m:[0m[32m9[0m[36m: in main[0m
[3m[2m 4 [0m[93m@ [0m [C][36m: in dofile[0m
[3m[2m 5 [0m[93m@ [0m[33mmods/lord/Core/builtin_ext/src/mod/require.lua[0m[97m:[0m[32m29[0m[36m: in require[0m
[3m[2m 6 [0m[93m@ [0m[33mmods/lord/Core/map/init.lua[0m[97m:[0m[32m4[0m[36m: in mod_init_function[0m
[3m[2m 7 [0m[93m@ [0m[33mmods/lord/Core/builtin_ext/src/mod.lua[0m[97m:[0m[32m80[0m[36m: in mod[0m
[3m[2m 8 [0m[93m@ [0m[33mmods/lord/Core/map/init.lua[0m[97m:[0m[32m3[0m[36m: in main[0m
[36mplayer_name:[0m "test_player"
[36m position:[0m {
x = 10,
y = 20,
z = 30,
}debug.measure(name, callback, print_result?)
Mede o tempo de execução da função.
local function heavy_calculation()
local sum = 0
for i = 1, 2000000 do
sum = sum + math.random(1, 100) + math.sin(i)
end
end
-- Medir com saída de resultado
debug.measure('calculation', heavy_calculation, true)
debug.measure('calculation', heavy_calculation, true)
debug.measure('calculation', heavy_calculation, true)
debug.measure('calculation', heavy_calculation, true)
debug.measure('calculation', heavy_calculation, true)
-- output:
-- Measure of [calculation]: Time: 42 ms ; Average: 42 ms
-- Measure of [calculation]: Time: 58 ms ; Average: 50 ms
-- Measure of [calculation]: Time: 58 ms ; Average: 53 ms
-- Measure of [calculation]: Time: 35 ms ; Average: 48 ms
-- Measure of [calculation]: Time: 33 ms ; Average: 45 ms
-- Medir sem saída
local time, avg, count = debug.measure('calculation', heavy_calculation)
print(time, avg, count)
local time, avg, count = debug.measure('calculation', heavy_calculation)
print(time, avg, count)
-- output:
-- 33.075 43.170833333333 6
-- 33.135 41.737142857143 7debug.mesure_print(name)
Produz estatísticas de medições anteriores name obtidas por chamadas a debug.measure(name, ....).
debug.mesure_print('calculation')
-- output:
-- Measure of [calculation]: Average time: 42 ms ; Last time: 33 ms ; Count of mesures: 7Global
errorf(message, ...)
Similar ao error() em Lua, mas message pode ser um string template com parâmetros especificados, similar ao string.format().
local player_name = nil
errorf('Jogador '%s' não encontrado', player_name)
-- Erro: Jogador 'nil' não encontradooutput (quando debug está habilitado):
[93m@ [0m[33mmods/lord/Core/map/src/map/Corridor.lua[0m[97m:[0m[32m9[0m
[32m++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++[0m
[1m[91mERROR:[0m
[91m Jogador `nil` não encontrado[0m
[1m[91mStack trace:[0m
[3m[2m 1 [0m[93m@[0m [C][36m: in error[0m
[3m[2m 2 [0m[93m@ [0m[33mmods/lord/Core/helpers/src/lua_ext/global.lua[0m[97m:[0m[32m9[0m[36m: in errorf[0m
[3m[2m 3 [0m[93m@ [0m[33mmods/lord/Core/map/src/map/Corridor.lua[0m[97m:[0m[32m12[0m[36m: in main[0m
[3m[2m 4 [0m[93m@ [0m [C][36m: in dofile[0m
[3m[2m 5 [0m[93m@ [0m[33mmods/lord/Core/builtin_ext/src/mod/require.lua[0m[97m:[0m[32m29[0m[36m: in require[0m
[3m[2m 6 [0m[93m@ [0m[33mmods/lord/Core/map/src/map.lua[0m[97m:[0m[32m9[0m[36m: in main[0m
[3m[2m 7 [0m[93m@ [0m [C][36m: in dofile[0m
[3m[2m 8 [0m[93m@ [0m[33mmods/lord/Core/builtin_ext/src/mod/require.lua[0m[97m:[0m[32m29[0m[36m: in require[0m
[3m[2m 9 [0m[93m@ [0m[33mmods/lord/Core/map/init.lua[0m[97m:[0m[32m4[0m[36m: in mod_init_function[0m
[3m[2m 10 [0m[93m@ [0m[33mmods/lord/Core/builtin_ext/src/mod.lua[0m[97m:[0m[32m80[0m[36m: in mod[0m
[3m[2m 11 [0m[93m@ [0m[33mmods/lord/Core/map/init.lua[0m[97m:[0m[32m3[0m[36m: in main[0m
[32m++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++[0mTratamento de erros no Luanti
WARNING
O stack trace conterá linhas extras, porque Luanti não passa o level especificado para core.error_handler().
errorlf(message, level, ...)
Como em errorf() você pode passar um string de formato e parâmetros, e também especificar o nível de trace.
errorlf('Erro nos dados', 3, 'valor: %d', 42)
-- Erro com trace 3 níveis acimaveja tratamento de erros no Luanti
assertf(condition, message, ...)
Similar ao assert() em Lua, mas como message você pode especificar um string de formato com parâmetros, similar ao string.format().
Chama
errorf()se a condiçãoconditionnão for atendida.
-- Continua execução se player existe, senão erro
local player = nil
assertf(player, 'Jogador `%s` não encontrado', player)IO
io.file_exists(name)
Verifica se um arquivo existe.
if io.file_exists('config.txt') then
print('Arquivo de configuração encontrado')
else
print('Arquivo de configuração ausente')
endio.dirname(path)
Retorna o diretório do caminho.
print(io.dirname('/home/user/project/file.txt')) -- '/home/user/project'
print(io.dirname('relative/path/file.txt')) -- 'relative/path'
print(io.dirname('file.txt')) -- '.'io.write_to_file(filepath, content, mode?)
Escreve conteúdo em um arquivo.
local success, error_code, error_message = io.write_to_file('data.txt', 'Hello, World!')
if success then
print('Dados gravados com sucesso')
else
print('Erro de gravação:', error_code, error_message)
end
-- Anexar ao final do arquivo
io.write_to_file('log.txt', 'Nova entrada\n', 'a')io.read_from_file(filepath, mode?)
Lê todo o conteúdo de um arquivo.
Retorna string com conteúdo do arquivo em caso de sucesso ou false, error_code, error_message em caso de erro.
local content = io.read_from_file('config.json')
if content then
print('Conteúdo do arquivo:', content)
else
print('Erro de leitura do arquivo')
endTratamento de erros
local success, error_code, error_message = io.read_from_file('nonexistent.txt')
if not success then
print('Erro:', error_code, error_message)
end
-- Erro: 2 nonexistent.txt: No such file or directoryou:
local success = io.read_from_file('nonexistent.txt')
if not success then
local error_code, error_message = io.get_file_error()
print('Erro:', error_code, error_message)
end
-- Erro: 2 nonexistent.txt: No such file or directoryLeitura em modo binário
local binary_content = io.read_from_file('image.png', 'rb')
if binary_content then
print('Tamanho do arquivo:', #binary_content, 'bytes')
endio.get_file_error()
Retorna o código e mensagem do último erro das funções io.read_from_file() ou io.write_to_file().
local success = io.read_from_file('nonexistent.txt')
if not success then
local error_code, error_message = io.get_file_error()
print('Erro:', error_code, error_message)
end
-- Output: Erro: 2 nonexistent.txt: No such file or directorylocal success = io.write_to_file('/readonly/file.txt', 'data')
if not success then
local error_code, error_message = io.get_file_error()
print('Erro de gravação:', error_code, error_message)
end
-- Output: Erro de gravação: 13 /readonly/file.txt: Permission deniedOS
os.DIRECTORY_SEPARATOR
Separador de diretório para o sistema operacional atual.
local DS = os.DIRECTORY_SEPARATOR
print(DS) -- '/' no Linux/Mac, '\' no Windows
print('folder' .. DS .. 'file.txt')
-- no Linux/Mac: 'folder/file.txt'
-- no Windows: 'folder\file.txt'