Перейти к содержимому
IS2511

parg - парсим аргументы из командной строки

Рекомендуемые сообщения

Отважно постим мимо Программы новичков

 

Наверняка за такое долгое время развития экосистемы OpenComputers кто-то уже писал свои обработчики аргументов.

Я даже видел какую-то на репе hpm (помянем). Для истории: https://gitlab.com/oc-programs/libxargs/raw/master/libxargs.lua

Но в основном всех устраивает shell.parse(...). Ну а меня нет.

 

Установка

Pastebin: https://pastebin.com/nSgXWHtp

Для ленивых:

# pastebin get nSgXWHtp /usr/lib/parg.lua

На всякий случай: https://gist.github.com/IS2511/96847fe185278b457505218b1c141f9d

Органический продукт! Разработан полностью на ocelot-desktop!

 

API

  • parg.parse(a: table): table: Принимает {...}, возвращает таблицу аргументов. Alias: parg(a: table): table.
  • parg.register(argument: string or table, argType: string, callback: function): nil: В argument название аргумента или список названий одного и того же аргумента (Например {"timeout", "t"}). В argType либо "flag", либо "value". В callback функция с 1 аргументом, это будет либо кол-во флагов, либо значение. Последний аргумент необязательный.
  • parg.unregister(argument: string or table, clearSame: boolean): nil: В argument название аргумента или список названий аргументов (Например {"timeout", "verbose"}). Если clearSame = true, то родственные аргументы также будут удалены. Последний аргумент необязательный, по умолчанию false. Я не знаю зачем эта функция, она просто есть.

 

Базовое использование

Механика библиотеки схожа c shell.parse.

Для быстроты приведу примеры. Программа для тестов будет такая (далее prog.lua):

local ser = require("serialization")
local parg = require("parg")

local arg = parg({...}) -- same as parg.parse({...})

print(ser.serialize(arg))

Попробуем вызвать с набором разных аргументов:

/home # prog test1 test2=test3 --test4 --test5=test6 -test7 -89=10
{"test1","test2=test3",[0]="/home/prog.lua",["9"]="10",test5="test6",["8"]=1,["7"]=1,t=2,s=1,e=1,test4=1}

Тут в принципе есть все основные варианты аргументов и их поведение. Самые простые аргументы типа "test1" и "test2=test3" далее не будут рассматриваться.

Как можно заметить появился также аргумент [0]="/home/prog.lua", это путь к файлу, который вызвал parg(), бывает иногда удобно. Этот аргумент так же далее не будет рассматриваться. (TODO: Есть мысли, что вызов debug.getinfo(3, "S") самый затратный из всей либы. Так ли это?)

 

Регистрация аргуметов

Типы

В библиотеке есть 2 типа аргументов: "flag" и "value". Первый всегда number, второй всегда string или nil. По умолчанию (без регистрации аргументов) все аргументы считаются "flag", если не используется =, тогда аргумент считается "value".

  • "flag" в значении имеют количество своих появлений. Например prog -xxx => {x=3}.
  • "value" в значении имеют строку со значением, указанным пользователем. Например prog -x=123, prog --x=123 => {x="123"}; prog --test=123 => {test="123"}.

 

Далее переходим к регистрации типов аргументов. Отредактируем prog.lua:

local ser = require("serialization")
local parg = require("parg")

parg.register({"timeout", "t"}, "value")
parg.register({"verbose", "v"}, "flag")

local arg = parg({...})

print(ser.serialize(arg))

Теперь некоторые аргументы имеют явный тип, а также родственников (Получается "--timeout" = "-t" = "--t").

Поскольку у "timeout" теперь явно тип "value", аргумент может принимать значения через пробел prog -t 10 => {t="10",verbose=0,v=0,timeout="10"}. Обратим внимание! Отсутсвие "flag" дает 0 в таблице аргументов.

"verbose" явно "flag", значит любые = больше не сработают prog -v=abc --verbose=def => {v=2,verbose=2}.

 

Каллбэки

Последняя фича - каллбэки. Добавим в prog.lua последние штрихи:

local ser = require("serialization")
local parg = require("parg")

local timeout, verbose
parg.register({"timeout", "t"}, "value", function (value) timeout = tonumber(value) or 10 end)
parg.register({"verbose", "v"}, "flag", function (count) verbose = count > 0 end)

parg({...})

print(ser.serialize({timeout,verbose}))

Попробуем. prog => {10,false}; prog -t abc => {10,false}; prog -t 20 -v => {20,true}; prog --verbose => {10,true}

Ну вот и все, библиотека работает. TODO: Добавить порядок обработки? Взаимосвязанные каллбэки?

 

Конец

Остался только один вопрос. Зачем? Почему у меня не используются регулярки? А нужны ли они?

На самом деле я просто забыл о них, не знаю есть ли смысл переделывать.

 

Комментарии и критика приветствуются

Первый пост, критика по оформлению также велком

Изменено пользователем IS2511
Добавил шутейку

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в тему...

×   Вы вставили отформатированное содержимое.   Удалить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отобразить как ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.


×
×
  • Создать...