Alors qu'est-ce que le « LAUX » ?
Pour comprendre le LAUX, il faut revenir légèrement en arrière... Un développeur nommé Metamist (Alexander Vision) à développé une sorte de LUA alternatif se prénommant LAU.
Ce projet est finalement arrêté, c'est pour cela que Sleeppy (Patrick Ratzow) a reprit le flambeau en créant le LAUX, celui-ci héritant du LAU.
Mais à quoi cela va-t-il m'avancer ?
Comme dit plus tôt, le LAUX est un LUA alternatif rajoutant des raccourcis pratiques, mais surtout une notion des classes avancée.
Comment l'installer ?
Installation
- Installer Node.JS.
- Cloner le répertoire GitLab suivant.
git clone https://gitlab.com/sleeppyy/laux
- Dans le même terminal, renseigner les commandes suivantes :
cd laux
npm install
npm link
- Si l'installation s'est déroulée avec succès ou alors pour vérifier que tout est bon, taper la commande suivante :
lauxc
- Si une ligne est sautée, mais que rien d'autre ne se passe, alors l'installation a été un succès.
Erreurs fréquentes
- "laux.ps1 cannot be loaded because runnings scripts is disabled on this system."
- Ouvrir une instance de
PowerShell
en tant qu'administrateur. - Taper la commande suivante :
set-executionpolicy unrestricted
- Valider en tapant "O".
- Ouvrir une instance de
Colorisation syntaxique
Par défaut, aucune colorisation syntaxique n'est fournie.
Visual Studio Code
- Si l'extension glua-enhanced est active alors :
- Se rendre ici
%USERPROFILE%\.vscode\extensions\venner.vscode-glua-enhanced-2.1.0\syntaxes
(La version risque de changer, alors éventuellement remplacer le2.1.0
par la version actuelle).
- Se rendre ici
- Sinon
%USERPROFILE%\.vscode\extensions
& chercher l'extension que vous utilisez.- Ensuite remplacer le fichier
lua.tmLanguage
par celui-ci.
- Ensuite remplacer le fichier
- Relancez
Visual Studio Code
.
Utilisation
Utilisation classique
Pour transpiler votre projet, il vous suffit de taper la commande suivante à la racine du projet :
- lauxc watch ./laux ./lua
Espaces de travail
Il est également possible d'utiliser des espacess de travail, ce qui signifie simplement d'utiliser un fichier de configuration.
Le fichier de configuration doit être nommé lauxconfig.json
et être situé dans le dossier racine du projet.
Cela vous permettra d'utiliser beaucoup plus d'options, dont l'une des plus intéréssantes est la « fusion ».
Vous pouvez fusionner plusieurs fichiers en un seul fichier de sortie.
Voici un exemple de fichier de configuration :
{
"path": {
"input": "./laux",
"output": "./lua"
},
"merges": [
{
"filesGlob": ["xenin_jobcreator/fields/**/*.laux"],
"output": "xenin_jobcreator/fields"
},
{
"filesGlob": ["xenin_jobcreator/currencies/**/*.laux"],
"output": "xenin_jobcreator/currencies"
}
]
}
Pour utiliser réellement les fonctions de « fusion », vous devez utiliser l'option de « release » qui se traduit par -r
.
Pas d'options
lauxc workspace
Fusion de fichiers
lauxc workspace -r
Qu'est-ce que cela ajoute ?
Fonctions
LAUX ajoute les « fat arrows » & les « thin arrows ».
Exemple de « Fat arrow »
local Foo = {}
Foo.Bar = (self) => print(self) end
--[[
local Foo = {}
Foo.Bar = function(self) print(self) end
]]
Exemple de « Thin arrow »
local Foo = {}
Foo.Bar = () -> print(self) end
--[[
local Foo = {}
Foo.Bar = function(self) print(self) end
]]
Types
Il s'agit d'une vérification de type en temps réel, donc ne la lancez pas dans quelque chose qui se lance à répétion & rapidement, comme à chaque frame.
-- LAUX
function Foo(bar: string)
-- Code
end
-- LUA
function Foo(bar)
local __lau_type = (istable(bar) and bar.__type and bar:__type()) or type(bar)
assert(__lau_type == "string", "Expected parameter `bar` to be type `string` instead of `" .. __lau_type .. "`")
end
Ceci accepte également les types multiples en utilisant le caractère |
.
-- LAUX
function Foo(bar: string|MyAddon.Bar)
-- Code
end
-- LUA
function Foo(bar)
local __lau_type = (istable(bar) and bar.__type and bar:__type()) or type(bar)
assert(__lau_type == "string" or __lau_type == "MyAddon.Bar", "Expected parameter `bar` to be type `string|MyAddon.Bar` instead of `" .. __lau_type .. "`")
end
Mutations
Le LAUX ajoute des mutations. Ce ne sont que de simples raccourcis...
x += 5 -- x = x + 5
x *= 2 -- x = x * 2
x /= 2 -- x = x / 2
x++ -- x = x + 1
x -= 1 -- x = x - 1 --> x-- n'éxiste pas
x ||= 2 -- x = x or 2
x ..= "me" -- x = x .. "me"
x %= 2 -- x = x % 2
Expressions raccourcies
Le LAUX ajoute des raccourcis pour faire rapidement une action générique.
stopif i > 5 -- if (i > 5) then return end
breakif i > 2 -- if (i > 2) then break end
continueif i > 8 -- if (i > 8) then continue end
Classes
Le LAUX ajoute des classes basés principalement sur le JavaScript
.
Syntaxe
[public] class Name [extends Parent]
end
Exemple
class Foo
-- On peut avoir des éléments statiques
static ENUMS = {}
-- Et des éléments non statiques
name = "Bar"
constructor(foobar: string)
self.foobar = foobar
end
setFoobar(val: string) self.foobar = val end
getFoobar() return self.foobar end
-- Si nous n'utilisons pas une classe publique, nous devons ajouter la fonction __type(). (Afin d'éviter que les noms soient les mêmes...)
__type()
return "MyAddon.Foo"
end
end
-- Pas besoin du mot-clé "new".
local foo1 = Foo()
class Bar extends Foo
constructor(foobar)
-- Vu que l'on fait de l'héritage, nous devons utiliser la fonction super().
-- Vous devez faire passer les arguments dont votre parent (extends) a besoin.
super(foobar)
-- Voyons le nom que notre classe parent nous donne.
print(self.name)
end
-- Seulement sur Bar, pas sur Foo.
uniqueMethod() end
end
Les classes par défaut sont privées (locales), nous pouvons donc les rendre publiques en utilisant le mot-clé public
.
public class XeninShop.Items.Health extends XeninShop.Item
-- Comme il s'agit d'une classe publique, vous n'avez pas besoin d'un type.
-- __type renverra automatiquement le nom de la classe.
end
Navigateur sûr
Le LAUX ajoute un « navigateur sûr ». Cela vous permet d'utiliser l'index de quelque chose dans un tableau sans avoir à vérifier si un élément existe.
-- LAUX
if (groups?[groupKind]?.members?.name) then
end
-- LUA
if (((groups and groups[groupKind]) and groups[groupKind].members) and groups[groupKind].members.name) then
end
Opérateur de diffusion
C'est le même opérateur que celui que l'on trouve dans JavaScript. Il fonctionne comme table.concat/unpack.
local a = { 2, 3 }
local b = { 1, ...a, 4 }
PrintTable(b) -- { 1, 2, 3, 4 }
Déconstruction
Pareil qu'en JavaScript
.
local tbl = { a = 5, b = 3 }
local { a, b } = tbl -- local a, b = tbl.a, tbl.b
print(a) -- 5
print(b) -- 3
Boucles
Vous pouvez faire une boucle générique, qui est l'équivalent de faire :
-- LUA
for i, v in pairs(tbl) do
end
-- LAUX
for i, v of tbl do
end
Il n'y a pas d'équivalent pour ipairs
.
Chaînes de caractères
Le LAUX ajoute le fait de pouvoir concaténer les chaînes de caractères comme en JavaScript
.
-- LAUX
local hello, world = "Hello", "World"
local message = `${hello} ${world}!`
-- LUA
local hello, world = "Hello", "World"
local message = tostring(hello) .. tostring(world) .. "!"
Méthodes asynchrones
Pour le moment elles nécéssitent XeninUI
& sont plutôt approximatives elles fonctionnent avec des Promises
.
-- LAUX
class Users
static async find(id)
return { money = 500 }
end
end
async function hasMoney(id, amt)
local { money } = await Users.find(id)
return money ?? 0 > amt
end
-- LUA
local Users
do
local _class_0
local _base_0 = {
__name = "Users",
__type = function(self)
return self.__name
end
}
_base_0.__index = _base_0
_class_0 = setmetatable({
__init = function(self) end,
__base = _base_0,
find = function(id)
local __laux_promise_5 = XeninUI.Promises.new()
return __laux_promise_5:resolve({
money = 500 })
end
}, {
__index = _base_0,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
return _self_0
end
})
Users = _class_0
end
function hasMoney(id, amt)
local __laux_promise_0 = XeninUI.Promises.new()
local __lauxi1
Users.find(id):next(function(__laux_result_2)
__lauxi1 = __laux_result_2
assert(__lauxi1 ~= nil, "cannot destructure nil value")
local money = __lauxi1.money
return __laux_promise_0:resolve((function() local __laux_nilish_coalescing_var = money if __laux_nilish_coalescing_var ~= nil then return __laux_nilish_coalescing_var else return 0 end end)() > amt)
end, function(__laux_error_3)
return __laux_promise_0:reject(__laux_error_3)
end)
return __laux_promise_0
end
Importations
Le LAUX ajoute les mots-clés import
, from
, as
.
-- LAUX
import
Service as LibService,
Cache as LibCache
from Xenin.Libs
LibService(...)
LibCache(...)
-- LUA
Xenin.Libs.Service(...)
Xenin.Libs.Cache(...)
Si tu as des questions ou tout simplement besoin d'aide, tu peux me retrouver sur le discord de GCA !