Búsqueda de sitios web

Analizando opciones de comando en Lua


Mi forma favorita de resolver el problema del análisis en Lua es alt-getopt.

Cuando ingresas un comando en tu terminal, generalmente hay opciones, también llamadas interruptores o banderas, que puedes usar para modificar la forma en que se ejecuta el comando. Esta es una convención útil definida por la especificación POSIX, por lo que, como programador, es útil saber cómo detectar y analizar opciones.

Como ocurre con la mayoría de los lenguajes, hay varias formas de resolver el problema de las opciones de análisis en Lua. Mi favorito es alt-getopt.

Instalación

La forma más sencilla de obtener y utilizar alt-getopt en su código es instalarlo con LuaRocks. Para la mayoría de los casos de uso, probablemente quieras instalarlo en el directorio de tu proyecto local:

$ mkdir local
$ luarocks --tree=local install alt-getopt 
Installing https://luarocks.org/alt-getopt-0.X.Y-1.src.rock
[...]
alt-getopt 0.X.Y-1 is now installed in /tux/myproject/local (license: MIT/X11)

Alternativamente, puedes descargar el código desde GitHub.

Agregar una biblioteca a su código Lua

Suponiendo que haya instalado la biblioteca localmente, puede definir la ruta de su paquete Lua y luego require el paquete alt-getopt:

package.path = package.path .. ';local/share/lua/5.1/?.lua'

local alt_getopt = require("alt_getopt")

Si lo ha instalado en una ubicación conocida del sistema, puede omitir la línea package.path (porque Lua ya sabe buscar bibliotecas en todo el sistema).

Ahora estás listo para analizar opciones en Lua.

Análisis de opciones en Lua

Lo primero que debe hacer para analizar las opciones es definir las opciones válidas que su aplicación puede aceptar. La biblioteca alt_getopt ve todas las opciones principalmente como opciones cortas, lo que significa que usted define las opciones como letras individuales. Puede agregar versiones largas más adelante.

Cuando defines opciones válidas, creas una lista delimitada por dos puntos (:), que es interpretada por la función get_opts proporcionada por alt-getopts .

Primero, cree algunas variables para representar las opciones. Las variables short_opt y optarg representan la opción corta y el argumento de la opción. Estos son nombres de variables arbitrarios, por lo que puedes llamarlos como quieras (siempre que sea un nombre válido para una variable).

La tabla long_opts debe existir, pero me resulta más fácil definir los valores de las opciones largas después de haber decidido las opciones cortas, así que déjala vacía por ahora.

local long_opts = {}

local short_opt
local optarg

Con esas variables declaradas, puede iterar sobre los argumentos proporcionados por el usuario, verificando si algún argumento coincide con su lista aprobada de opciones cortas válidas.

Si se encuentra una opción válida, utiliza la función pairs en Lua para extraer el valor de la opción.

Para crear una opción que no acepte ningún argumento propio pero que esté activada o desactivada (a menudo denominada interruptor), coloque la opción corta desea definir a la derecha de un carácter de dos puntos (:).

En este ejemplo, he creado un bucle para comprobar la opción corta -a, que es un modificador:

short_opt,optarg = alt_getopt.get_opts (arg, ":a", long_opts)
local optvalues = {}
for k,v in pairs (short_opt) do
   table.insert (optvalues, "value of " .. k .. " is " .. v .. "\n")
end

table.sort (optvalues)
io.write (table.concat (optvalues))

for i = optarg,#arg do
   io.write (string.format ("ARGV [%s] = %s\n", i, arg [i]))
end

Al final de este código de muestra, incluí un bucle for para iterar sobre los argumentos restantes en el comando porque cualquier cosa que no se detecte como una opción válida debe ser un argumento (probablemente un nombre de archivo, URI o lo que sea que su aplicación opera).

Pruebe el código:

$ lua test.lua -a 
value of a is 1

El script de prueba detectó con éxito la opción -a y le asignó un valor de 1 para representar que existe.

Inténtalo de nuevo con un argumento extra:

$ lua test.lua -a hello
value of a is 1
ARGV [2] = hello

Opciones con argumentos

Algunas opciones requieren un argumento propio. Por ejemplo, es posible que desee permitir que el usuario apunte su aplicación a un archivo de configuración personalizado, establezca un atributo en un color o establezca la resolución de un gráfico. En alt_getopt, las opciones que aceptan argumentos se colocan a la izquierda de los dos puntos (:) en la lista corta de opciones.

short_opt,optarg = alt_getopt.get_opts (arg, "c:a", long_opts)

Pruebe el código:

$ lua test.lua -a -c my.config
value of a is 1
value of c is my.config

Inténtalo de nuevo, esta vez con un argumento extra:

$ lua test.lua -a -c my.config hello
value of a is 1
value of c is my.config
ARGV [4] = hello

Opciones largas

Las opciones cortas son excelentes para los usuarios avanzados, pero no suelen ser muy memorables. Puede crear una tabla de opciones largas que apunten a opciones cortas para que los usuarios puedan aprender las opciones largas antes de abreviar sus comandos con opciones de una sola letra.

local long_opts = {
   alpha = "a",
   config = "c"
}

Los usuarios ahora pueden elegir entre opciones largas y cortas:

$ lua test.lua --config my.config --alpha hello
value of a is 1
value of c is my.config
ARGV [4] = hello

Análisis de opciones

Aquí está el código de demostración completo para su referencia:

#!/usr/bin/env lua
package.path = package.path .. ';local/share/lua/5.1/?.lua'

local alt_getopt = require("alt_getopt")

local long_opts = {
   alpha = "a",
   config = "c"
}

local short_opt
local optarg

short_opt,optarg = alt_getopt.get_opts (arg, "c:a", long_opts)
local optvalues = {}
for k,v in pairs (short_opt) do
   table.insert (optvalues, "value of " .. k .. " is " .. v .. "\n")
end

table.sort (optvalues)
io.write (table.concat (optvalues))

for i = optarg,#arg do
   io.write (string.format ("ARGV [%s] = %s\n", i, arg [i]))
end

Hay más ejemplos en el repositorio Git del proyecto. Incluir opciones para sus usuarios es una característica importante para cualquier aplicación y Lua lo hace fácil. Hay otras bibliotecas además de alt_getopt, pero ésta me parece fácil y rápida de usar.

Artículos relacionados: