Ликбез по Lua

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

Ликбез по Lua

Postby John Doe » Mon 02 Jul, 2012 05:41

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

Для того, чтобы получить начальное представление о языке достаточно почитать какую-нибудь короткую обзорную статью, например:
Для более близкого знакомства рекомендую эти документы:

gene.pavlovsky
Posts: 157
Joined: Tue 11 Aug, 2015 16:53
Has thanked: 11 times

Ликбез по Lua

Postby gene.pavlovsky » Thu 10 Nov, 2016 14:19

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: 4954
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 11 times
Been thanked: 124 times

Ликбез по Lua

Postby Shmuel » Thu 10 Nov, 2016 15:08

1. Общепринятая практика - возвращать в таблице, например return { substr=substr; charAt=charAt }
2. unicode.utf8.substr = substr

User avatar
John Doe
Бюрократ
Posts: 11042
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 9 times
Been thanked: 62 times

Ликбез по Lua

Postby John Doe » Thu 10 Nov, 2016 15:53

gene.pavlovsky wrote:Source of the post эти ф-ции появлялись в 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()
Last edited by John Doe on Thu 10 Nov, 2016 16:25, edited 1 time in total.

gene.pavlovsky
Posts: 157
Joined: Tue 11 Aug, 2015 16:53
Has thanked: 11 times

Ликбез по Lua

Postby gene.pavlovsky » Thu 10 Nov, 2016 17:33

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

John Doe, lua и его идиомы меня скорее не радуют, чем радуют. Если индекс вычисляется как сложное выражение, его приходится или дублировать, или пихать в зачастую далее ненужную переменную - некрасиво, особенно когда привык к наличию в string-е большого кол-ва удобных ф-ций. Если я свои скрипты буду выкладывать, я постараюсь включить тела свои require в шапку скрипта, или дать ссылку, если это сторонние модули.

User avatar
John Doe
Бюрократ
Posts: 11042
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 9 times
Been thanked: 62 times

Ликбез по Lua

Postby John Doe » Thu 10 Nov, 2016 18:57

gene.pavlovsky wrote:Source of the post Если я свои скрипты буду выкладывать, я постараюсь включить тела свои require в шапку скрипта
Всё равно не очень хорошая практика: нестандартные функции в стандартных библиотеках.
Кто-то иначе захочит определить например, будет конфликт.

Smitis
Posts: 1431
Joined: Fri 18 Mar, 2005 12:51
Location: Питер
Has thanked: 9 times
Been thanked: 21 times
Contact:

Ликбез по Lua

Postby Smitis » Thu 10 Nov, 2016 20:44

local ограничивает действие блоком/файлом. Без local - если есть глобальная переменная, используется она. Иначе - локальная.
Для модулей принято возвращать результаты в виде таблицы return {substr=substr,charAt=charAt,charCodeAt=charCodeAt}
Можно создать _macroinit.lua и там прописать типа _G.substr = function(str, index, length) что-то end функция будет глобальной без всяких модулей. Но метод годится только для локального (личного) использования.
Разум когда-нибудь победит.

Smitis
Posts: 1431
Joined: Fri 18 Mar, 2005 12:51
Location: Питер
Has thanked: 9 times
Been thanked: 21 times
Contact:

Ликбез по Lua

Postby Smitis » Thu 10 Nov, 2016 20:57

gene.pavlovsky wrote:Если индекс вычисляется как сложное выражение, его приходится или дублировать, или пихать в зачастую далее ненужную переменную - некрасиво, особенно когда привык к наличию в string-е большого кол-ва удобных ф-ций.

Что-то не осилил, сорри. Если результат выражения нужен более одного раза, как можно обойтись без промежуточного сохранения результатов? А переменные можно использовать local.
Разум когда-нибудь победит.

User avatar
John Doe
Бюрократ
Posts: 11042
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 9 times
Been thanked: 62 times

Ликбез по Lua

Postby John Doe » Thu 10 Nov, 2016 21:35

Smitis wrote:Source of the post Если результат выражения нужен более одного раза, как можно обойтись без промежуточного сохранения результатов?
Имелось ввиду функцию определить, в которой эта кухня будет скрыта.

gene.pavlovsky
Posts: 157
Joined: Tue 11 Aug, 2015 16:53
Has thanked: 11 times

Ликбез по Lua

Postby gene.pavlovsky » Thu 10 Nov, 2016 23:38

John Doe Согласен, что для обмена кодом практика не очень хорошая. Но надо же как-то с этим lua выживать...
Smitis str:sub(startIndex + anotherStr:len() + 2, startIndex + anotherStr:len() + 4) или str:substr(startIndex + anotherStr:len() + 2, 3) - имел в виду вот это.

Smitis
Posts: 1431
Joined: Fri 18 Mar, 2005 12:51
Location: Питер
Has thanked: 9 times
Been thanked: 21 times
Contact:

Ликбез по Lua

Postby Smitis » Sat 12 Nov, 2016 12:34

Для данного конкретного случая mf.substr
  1. unicode.utf8.substr = mf.substr
  2. local a = "1234567890"
  3. mf.msgbox("",a:substr(5,3))
Разум когда-нибудь победит.

gene.pavlovsky
Posts: 157
Joined: Tue 11 Aug, 2015 16:53
Has thanked: 11 times

Ликбез по Lua

Postby gene.pavlovsky » Sat 12 Nov, 2016 13:45

Увидел теперь. Интересно, в чём разница между, скажем, math.min и mf.min?

User avatar
John Doe
Бюрократ
Posts: 11042
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 9 times
Been thanked: 62 times

Ликбез по Lua

Postby John Doe » Sat 12 Nov, 2016 13:51

gene.pavlovsky wrote:Source of the post в чём разница между, скажем, math.min и mf.min
Первая реализована Lua, вторая фаром (ещё до Lua), и оставлена "для совместимости".
Избавиться от дублирования в LuaMacro

Shmuel
Posts: 4954
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 11 times
Been thanked: 124 times

Ликбез по Lua

Postby Shmuel » Sat 12 Nov, 2016 14:09

John Doe wrote:Source of the post Избавиться от дублирирования в LuaMacro

Shmuel
Posts: 4954
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 11 times
Been thanked: 124 times

Ликбез по Lua

Postby Shmuel » Sat 12 Nov, 2016 14:21

Вообще-то есть разница: 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: 157
Joined: Tue 11 Aug, 2015 16:53
Has thanked: 11 times

Ликбез по Lua

Postby gene.pavlovsky » Sat 12 Nov, 2016 17:56

Чёртова обратная совместимость! :)

IgorZ
Posts: 427
Joined: Wed 13 Jul, 2011 03:32
Has thanked: 4 times
Been thanked: 6 times

Ликбез по Lua

Postby IgorZ » Thu 29 Dec, 2016 11:33

Вопрос по работе метаметодов в 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.

Shmuel
Posts: 4954
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 11 times
Been thanked: 124 times

Ликбез по Lua

Postby Shmuel » Thu 29 Dec, 2016 11:54

IgorZ wrote:Source of the post А вот с __len, __ipairs, __pairs что-то, кажется, не так.
Перечисленные метаметоды не работают для таблиц в Lua 5.1, в чём легко убедиться из мануала. Последние два вообще отсутствуют в Lua 5.1.
Если скомпилировать LuaJIT с ключом -DLUAJIT_ENABLE_LUA52COMPAT, тогда эти метаметоды должны работать.


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

Who is online

Users browsing this forum: No registered users and 3 guests