Ликбез по Lua

Столкнулись с проблемой в использовании макросов? Здесь можно получить помощь.
User avatar
John Doe
Бюрократ
Posts: 13801
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 72 times
Been thanked: 425 times
Contact:

Ликбез по Lua

Post by John Doe »

В данной теме задаём вопросы по Lua.

Для того, чтобы получить начальное представление о языке достаточно почитать какую-нибудь короткую обзорную статью, например:
Для более близкого знакомства рекомендую эти документы:
gene.pavlovsky
Posts: 170
Joined: Tue 16 Feb, 2010 17:55
Location: Luxembourg
Has thanked: 11 times
Been thanked: 9 times
Contact:

Ликбез по Lua

Post by gene.pavlovsky »

Latest post of the previous page:

Сделал вот такие три функции


Хочется их вынести в modules/stringutil.lua и подключать его из макросов, где нужно
Вопросы:
1) Если просто убрать local, и подключать модуль require "stringutil" - ф-ции становятся доступными и работают.
Красиво ли так поступать, или есть какая-то другая общепринятая практика? При проверке luacheck-ом он выдаёт warnings: setting non-standard global variable "substr" и остальные.
2) В идеале хочется, чтоб при подключении require "stringutil" эти ф-ции появлялись в string, и можно было писать str:substr(...).
Попробовал добавить string.substr = substr в конце stringutil.lua - ошибок нет, но при попытке задействовать str:substr(...) ругается на substr - nil value. Как бы это оформить?
Shmuel
Posts: 6815
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 41 times
Been thanked: 526 times

Ликбез по Lua

Post by Shmuel »

1. Общепринятая практика - возвращать в таблице, например return { substr=substr; charAt=charAt }
2. unicode.utf8.substr = substr
User avatar
John Doe
Бюрократ
Posts: 13801
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 72 times
Been thanked: 425 times
Contact:

Ликбез по Lua

Post by John Doe »

gene.pavlovsky wrote: эти ф-ции появлялись в string, и можно было писать str:substr(...).
При обмене скриптами рано или поздно возникнет ситуация, когда этих функций у конечного пользователя не окажется, а вы этого и не заметите, ведь при таком использовании не требуется require в каждом скрипте.

Вообще, глядя на приведённые функции, кажется что их лучше заменить идиомами lua.

substr: str:sub(index or 1,length and ((index or 1)+ length-1) or -1 или

charAt: str:sub(index or 1, index or 1)

charCodeAt: str:byte(index) или charAt(index):byte()
gene.pavlovsky
Posts: 170
Joined: Tue 16 Feb, 2010 17:55
Location: Luxembourg
Has thanked: 11 times
Been thanked: 9 times
Contact:

Ликбез по Lua

Post by gene.pavlovsky »

Shmuel, благодарю, оба варианта работают.

John Doe, lua и его идиомы меня скорее не радуют, чем радуют. Если индекс вычисляется как сложное выражение, его приходится или дублировать, или пихать в зачастую далее ненужную переменную - некрасиво, особенно когда привык к наличию в string-е большого кол-ва удобных ф-ций. Если я свои скрипты буду выкладывать, я постараюсь включить тела свои require в шапку скрипта, или дать ссылку, если это сторонние модули.
User avatar
John Doe
Бюрократ
Posts: 13801
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 72 times
Been thanked: 425 times
Contact:

Ликбез по Lua

Post by John Doe »

gene.pavlovsky wrote: Если я свои скрипты буду выкладывать, я постараюсь включить тела свои require в шапку скрипта
Всё равно не очень хорошая практика: нестандартные функции в стандартных библиотеках.
Кто-то иначе захочит определить например, будет конфликт.
User avatar
Smitis
Posts: 1709
Joined: Fri 18 Mar, 2005 12:51
Location: Питер
Has thanked: 23 times
Been thanked: 55 times

Ликбез по Lua

Post by Smitis »

local ограничивает действие блоком/файлом. Без local - если есть глобальная переменная, используется она. Иначе - локальная.
Для модулей принято возвращать результаты в виде таблицы return {substr=substr,charAt=charAt,charCodeAt=charCodeAt}
Можно создать _macroinit.lua и там прописать типа _G.substr = function(str, index, length) что-то end функция будет глобальной без всяких модулей. Но метод годится только для локального (личного) использования.
Разум когда-нибудь победит.
User avatar
Smitis
Posts: 1709
Joined: Fri 18 Mar, 2005 12:51
Location: Питер
Has thanked: 23 times
Been thanked: 55 times

Ликбез по Lua

Post by Smitis »

gene.pavlovsky wrote:Если индекс вычисляется как сложное выражение, его приходится или дублировать, или пихать в зачастую далее ненужную переменную - некрасиво, особенно когда привык к наличию в string-е большого кол-ва удобных ф-ций.
Что-то не осилил, сорри. Если результат выражения нужен более одного раза, как можно обойтись без промежуточного сохранения результатов? А переменные можно использовать local.
Разум когда-нибудь победит.
User avatar
John Doe
Бюрократ
Posts: 13801
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 72 times
Been thanked: 425 times
Contact:

Ликбез по Lua

Post by John Doe »

Smitis wrote: Если результат выражения нужен более одного раза, как можно обойтись без промежуточного сохранения результатов?
Имелось ввиду функцию определить, в которой эта кухня будет скрыта.
gene.pavlovsky
Posts: 170
Joined: Tue 16 Feb, 2010 17:55
Location: Luxembourg
Has thanked: 11 times
Been thanked: 9 times
Contact:

Ликбез по Lua

Post by gene.pavlovsky »

John Doe Согласен, что для обмена кодом практика не очень хорошая. Но надо же как-то с этим lua выживать...
Smitis str:sub(startIndex + anotherStr:len() + 2, startIndex + anotherStr:len() + 4) или str:substr(startIndex + anotherStr:len() + 2, 3) - имел в виду вот это.
User avatar
Smitis
Posts: 1709
Joined: Fri 18 Mar, 2005 12:51
Location: Питер
Has thanked: 23 times
Been thanked: 55 times

Ликбез по Lua

Post by Smitis »

Для данного конкретного случая mf.substr
  1. unicode.utf8.substr = mf.substr
  2.  
  3. local a = "1234567890"
  4.  
  5. mf.msgbox("",a:substr(5,3))
Разум когда-нибудь победит.
gene.pavlovsky
Posts: 170
Joined: Tue 16 Feb, 2010 17:55
Location: Luxembourg
Has thanked: 11 times
Been thanked: 9 times
Contact:

Ликбез по Lua

Post by gene.pavlovsky »

Увидел теперь. Интересно, в чём разница между, скажем, math.min и mf.min?
User avatar
John Doe
Бюрократ
Posts: 13801
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 72 times
Been thanked: 425 times
Contact:

Ликбез по Lua

Post by John Doe »

gene.pavlovsky wrote: в чём разница между, скажем, math.min и mf.min
Первая реализована Lua, вторая фаром (ещё до Lua), и оставлена "для совместимости".
http://forum.farmanager.com/viewtopic.php?f=15&t=7671
Shmuel
Posts: 6815
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 41 times
Been thanked: 526 times

Ликбез по Lua

Post by Shmuel »

John Doe wrote: Избавиться от дублирирования в LuaMacro
Shmuel
Posts: 6815
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 41 times
Been thanked: 526 times

Ликбез по Lua

Post by Shmuel »

Вообще-то есть разница: math.min и math.max принимают произвольное количество аргументов, а mf.min и mf.max - только два.
Last edited by Shmuel on Sat 12 Nov, 2016 14:23, edited 1 time in total.
gene.pavlovsky
Posts: 170
Joined: Tue 16 Feb, 2010 17:55
Location: Luxembourg
Has thanked: 11 times
Been thanked: 9 times
Contact:

Ликбез по Lua

Post by gene.pavlovsky »

Чёртова обратная совместимость! :)
IgorZ
Posts: 790
Joined: Wed 13 Jul, 2011 03:32
Has thanked: 15 times
Been thanked: 93 times

Ликбез по Lua

Post by IgorZ »

Вопрос по работе метаметодов в Far.

К примеру, __index, __newindex, __call работают без проблем. А вот с __len, __ipairs, __pairs что-то, кажется, не так. Для примера:

Code: Select all

local t = {}
setmetatable(t,{
  __len = function(self) return 3 end, --Размер этого "массива" теперь всегда 3
})
for i = 1, 8 do table.insert(t, i) end -- В массиве теперь 8 элементов,
far.Show(#t) -- но результат всё равно должен быть 3
выдаёт вместо трёх - восемь. А если заменить функцию на

Code: Select all

  __len = function(self) error"__len!!!" end, --Размер этого "массива" теперь не узнать
то error не срабатывает. В общем, такое впечатление, что часть метаметодов не заменяются на пользовательские обработчики. Хотя Lua о них знает: в lua51.dll содержится строка
__index__newindex__gc__mode__eq__len__lt__le__concat__call__add__sub__mul__div__mod__pow__unm__metatable__tostring__new__pairs__ipairs.
Post Reply

Return to “Нужна помощь”