Лепикоршев
Удобство разработки ценнее
Snusmumriken
Ну допустим, у меня вот такой вот запускатель луёвых скриптов. Я в нём запускаю по шорткату из IDE.
Snusmumriken
Суть в том, что он автоматически начинает брать луёвые либы из той же директории, что и запущенный скрипт (exe, в твоём случае), и это довольно неплохо.
И при луёвой ошибке, консольное окошко не закрывается просто так, а предоставляет debug-режим. То самое удобство разработки, о котором ты говорил.
Snusmumriken
Вот если вморозить его в C-код, и там же захардкодить scrPath на "main.lua рядом с exe" — он будет запускать main.lua в максимально удобном виде для разработки. Круто, да?
Лепикоршев
Или ты его как раз и запускаешь через C-оболочку?
Snusmumriken
В моём случае, я просто запускаю все обычные луа-скрипты примерно следующей CMD-командой:
Тот код который я показал
V
luajit c:/loader.lua c:/loadable.lua
^
скрипт, который я хочу запустить loader'ом
Я юзаю шорткаты notepad++, но можно вплавить loader в сишку, с минимальными изменениями, чтобы он запускал нужное тебе.
Snusmumriken
Луа-скрипт, который запускает другой луа-скрипт, предоставляя ништяки и оставляя минимум собственных следов и предоставляя дебаг в конце исполнения/при ошибке.
Тут даже traceback не ломается, он такой же как при запуске напрямую, я поработал над этим.
Snusmumriken
Lucky
Асанте сана!
Kirill
Всем привет, подрубил LRDB, работает но всплыл момент подгрузки исходов: пока исполняется строка всё норм, а как появляется require - дебагер пытается грузить файл. но отлаживаю embeded linux, дебагер под win. Может подставить в require загрузку в строку и выполнение строки? если так где такое посмотреть как делают?
Ameliance
Приветствую, есть пару вопросов, буду признателен, если кто поможет разобраться)
Ameliance
#вопрос
Подскажите, когда может быть полезна данная конструкция (возвращение функции в функции)?
-- Closures and anonymous functions are ok:
function adder(x)
-- The returned function is created when adder is
-- called, and remembers the value of x:
return function (y) return x + y end
end
a1 = adder(9)
a2 = adder(36)
print(a1(16)) --> 25
print(a2(64)) --> 100
Igor
Leon174
Там же написано про замыкания (closures) и анонимные функции. С этой информацией можно сразу припасть к первоисточнику знаний...
https://www.lua.org/pil/6.1.html
Ameliance
Leon174
Ну, это для начала только годится, для ознакомления. Дальше lua.org и PiL. Последняя совсем не дефицит, в сети находится без проблем.
https://www.lua.org/pil/
Snusmumriken
Ameliance
Ну, это для начала только годится, для ознакомления. Дальше lua.org и PiL. Последняя совсем не дефицит, в сети находится без проблем.
https://www.lua.org/pil/
Спасибо, гляну, но это не главный вопрос, мне кажется этой штукой я вряд ли буду пользоваться) Просто нужно все равно разобраться, вдруг пригодится
Я не ас в программировании и это как хобби больше. На Lua программирую только скрипты для Reaper DAW. Вчера решил почитать, кое что по таблицам, метатаблицам и методам, освежить, а кое где продвинутся, но есть парочку вопросов, которые актуальны сейчас для меня больше. еще немного почитаю и если не разберусь, то задам)
Snusmumriken
#вопрос
Подскажите, когда может быть полезна данная конструкция (возвращение функции в функции)?
-- Closures and anonymous functions are ok:
function adder(x)
-- The returned function is created when adder is
-- called, and remembers the value of x:
return function (y) return x + y end
end
a1 = adder(9)
a2 = adder(36)
print(a1(16)) --> 25
print(a2(64)) --> 100
1. Итераторы:
function iter(tbl)
local i = #tbl + 1
return function()
i = i - 1
if not tbl[i] then return end
return i, tbl[i]
end
end
local t = {"a", "b", "c"}
for i, v in iter(t) do
print(i, v)
end
> 3 c
> 2 b
> 1 a
2. Какие-нибудь сборщики значений:
function collector()
local res = {}
return function(v)
if not v then return unpack(res) end
res[#res + 1] = v
end
end
local cl = collector()
cl(1)
cl(2)
cl(3)
a, b, c = cl()
print(a, b, c)
>1 2 3
3. Ещё что-нибудь смешное и забавное.
Arslan
unpack разбивает таблицу на переменные?
Arslan
Извиняюсь за внезапное вторжение
Snusmumriken
1. Итераторы:
function iter(tbl)
local i = #tbl + 1
return function()
i = i - 1
if not tbl[i] then return end
return i, tbl[i]
end
end
local t = {"a", "b", "c"}
for i, v in iter(t) do
print(i, v)
end
> 3 c
> 2 b
> 1 a
2. Какие-нибудь сборщики значений:
function collector()
local res = {}
return function(v)
if not v then return unpack(res) end
res[#res + 1] = v
end
end
local cl = collector()
cl(1)
cl(2)
cl(3)
a, b, c = cl()
print(a, b, c)
>1 2 3
3. Ещё что-нибудь смешное и забавное.
Я, например, использовал подобные штуки для создания "функций-генераторов" математических функций:
-- осциллятор, пихаем общую частоту/частоту/амплитуду
local function osc(freq, ampl, rate)
local sin = math.sin
local tau = math.pi * 2
local freq = freq or 400
local ampl = ampl or 1
local rate = rate or 44100
local dt = 1/rate
local time = 0
return function(fr)
time = time + (fr or freq) * dt
return sin(tau * time) * ampl
end
end
local o = osc(400, 1, 44100) --> новый осциллятор
local samples = {}
for i = 1, 100 do
-- генерим синусоиду
samples[i] = o()
end
-- подаём samples на звуковуху ))
Snusmumriken
unpack разбивает таблицу на переменные?
Да, разбивает таблицу-массив на отдельные значения.
a, b, c = unpack({1, 2, 3, 4})
print(a, c) --> 1 3
То ли в 5.2, то ли в 5.3, её перевели в библиотеку table, то есть используется как table.unpack(...).
Не стоит пытаться распаковывать таблицы больше чем на тысячу-другую значений, это может быть вредно.
Inellok
Так, какие - то функции - замыкания...
Inellok
хм
Inellok
Почему? Тут есть новая информация и знания.
Leon174
Спасибо, гляну, но это не главный вопрос, мне кажется этой штукой я вряд ли буду пользоваться) Просто нужно все равно разобраться, вдруг пригодится
Я не ас в программировании и это как хобби больше. На Lua программирую только скрипты для Reaper DAW. Вчера решил почитать, кое что по таблицам, метатаблицам и методам, освежить, а кое где продвинутся, но есть парочку вопросов, которые актуальны сейчас для меня больше. еще немного почитаю и если не разберусь, то задам)
"...мне кажется этой штукой я вряд ли буду пользоваться) Просто нужно все равно разобраться, вдруг пригодится"
А не всеми фичами и нужно пользоваться, какие-то вещи могут меняться, удаляться. Какие-то могут быть спорными, но точно никто не скажет, нужно оно или нет, мнения разные бывают. Я вот про миксины в typescript с утра читал. Кто-то говорит, что это дрянь редкостная, кто-то, что они (первые) дураки и готовить миксины не умеют. Но примерно знать нужно, это точно, чтобы не велосипедить потом. Я вот понятия не имею, нужны ли мне миксины и вообще тайпскрипт. Что-то примерно для себя понял, если приспичит, вернусь за подробностями.
А по замыканиям еще можно по темам джаваскрипта посмотреть, там это популярная штука.
Inellok
Я вот не знал, что можно свои итераторы писать.
Inellok
Всё равно не понял, как ето работает👌
Inellok
А почему вредны?
Snusmumriken
А почему вредны? Ответь на вопрос, пожалуйста : )
Я это уже объяснял, пришло время вспоминать или выводить самостоятельно.
Inellok
Может, потому что это неприменимо для меня?
Inellok
Ну ты писал, что я лез туда, куда на текущий момент нет смысла лезть, да и знаний моих там не хватит.
Ameliance
"...мне кажется этой штукой я вряд ли буду пользоваться) Просто нужно все равно разобраться, вдруг пригодится"
А не всеми фичами и нужно пользоваться, какие-то вещи могут меняться, удаляться. Какие-то могут быть спорными, но точно никто не скажет, нужно оно или нет, мнения разные бывают. Я вот про миксины в typescript с утра читал. Кто-то говорит, что это дрянь редкостная, кто-то, что они (первые) дураки и готовить миксины не умеют. Но примерно знать нужно, это точно, чтобы не велосипедить потом. Я вот понятия не имею, нужны ли мне миксины и вообще тайпскрипт. Что-то примерно для себя понял, если приспичит, вернусь за подробностями.
А по замыканиям еще можно по темам джаваскрипта посмотреть, там это популярная штука.
по этому нужно разобраться... я когда для себя понял наконец как юзатьcase в js, так почувствовал себя дураком полным, что раньше не вникал (в луа же нет их?)
Snusmumriken
Ага, а ещё, лишний мусор в голове. Смотрел советского Шерлока Холмса? Он не был в курсе что земля вращается вокруг солнца, но ему было плевать: на его деятельности это никак не отражается. Так-то это мусор, которым забивают голову, и только нескольким людям из тысячи, это информация оказывается действительно полезной, ибо они используют её в профессиональной деятельности.
Лямбды и замыкания тебе понадобятся ОЧЕНЬ нескоро, если понадобятся вообще.
Leon174
по этому нужно разобраться... я когда для себя понял наконец как юзатьcase в js, так почувствовал себя дураком полным, что раньше не вникал (в луа же нет их?)
Case в смысле switch? Не, в луа switch отсутствует. Там много чего нет, что бы очень хотелось. Ну, что поделать, "нет в жизне щасья". Я вот писал (скорее, мучился) на предметно-ориентированном языке, в котором не было ни одного вида циклов. Поддержка баз данных была, подержка родной геометрии была, даже модульность была, а вот циклов не было. Только метки и безусловный переход. И всё, жуй, не обляпайся. Ничего, не помер, писал как-то. Правда, потом туда python подвезли и про то сатанинское поделие я почти позабыл.
"Reaper DAW" - прикольно, куда только луа не воткнули.
Mons
"тернарники" плохо работают, если в качестве значений бывают нужны nil или false ;)
Leon174
Да вот сразу, чего уж тут. Там, кстати, как и у Снуса используются анонимные функции. К вопросу о нужности.
http://lua-users.org/wiki/SwitchStatement
Ameliance
Есть тернарники:
local a = "foo"
local v = 100500
v = a == "foo" and (v + 1)
or a == "bar" and (v - 1)
or a == "baz" and 0
or -1
Или таблицы-свитчи:
local switch = {
["foo"] = function(v) return v + 1 end,
["bar"] = function(v) return v - 1 end,
["baz"] = function(v) return 0 end,
}
local a = "foo"
local v = 100500
v = switch[a] and switch[a](v) or 0
а-а-а-а... мои мозги пока не вывозят это все... наверное потому что я не понимаю некоторые моменты, потому что никогда не видел... (вчера что-то похожее в коде увидел, но тоже не до конца понял a = value or 0)
1.
v = a == "foo" and (v + 1)
or a == "bar" and (v - 1)
or -1
и 2.
v = switch[a] and switch[a](v) or 0
я правильно понимаю?
1. v присваивается
(v + 1)
, если а равно
"foo"
, а если a равно
"bar"
, то v присваивается
(v + 1), а если ни то v присваивается
-1
?
2. если a равно "foo", то в функцию switch.foo в качестве аргумента v ? посылается 100500
Ameliance
хм.. почему телеграм разбил объяснение 1. на абзаци...
Arslan
Конструкция cond and exp or exp - подобие краткого условия
Arslan
Как в си "cond?exp:exp"
Snusmumriken
Ага
Snusmumriken
a = cond and exp1 or exp2, так немножко понятнее
Ameliance
ок, это понял, а как насчет 1.?
Snusmumriken
ок, это понял, а как насчет 1.?
v = a == "foo" and (v + 1)
or a == "bar" and (v - 1)
or -1
==
local v = 100500
if a == "foo" then
v = v + 1
elseif a == "bar" then
v = v - 1
else
v = -1
end
Ameliance
a = value or 0
а тут получается если value = nil, то присваивается 0?
Leon174
http://www.lua.org/manual/5.3/manual.html#3.4.5
Ameliance
Ameliance
Snusmumriken
а-а-а-а... мои мозги пока не вывозят это все... наверное потому что я не понимаю некоторые моменты, потому что никогда не видел... (вчера что-то похожее в коде увидел, но тоже не до конца понял a = value or 0)
1.
v = a == "foo" and (v + 1)
or a == "bar" and (v - 1)
or -1
и 2.
v = switch[a] and switch[a](v) or 0
я правильно понимаю?
1. v присваивается
(v + 1)
, если а равно
"foo"
, а если a равно
"bar"
, то v присваивается
(v + 1), а если ни то v присваивается
-1
?
2. если a равно "foo", то в функцию switch.foo в качестве аргумента v ? посылается 100500
Во втором —
v = switch[a] and switch[a](v) or 0
switch[a] and switch[a](v) — проверяет, что в свитче есть значение [a], и если есть — вызывает его. Если такого нет — переходит к следующему or, и выставляет 0 как дефолт.
Inellok
Snusmumriken
Оно считается true, и это проблема. NaN очень сложно проверить на NaN, потому что оно ведёт себя как число, а при попытке арифметики — дропает приложение. Я на этом много костылил.
Поэтому просто не дели на ноль, ок да?
Inellok
Ну в обычно луа ведь есть NaN или нет?
Snusmumriken
Есть. Но как скрытая фигня. Прекрати делить на ноль!
Leon174
спасибо
Вот еще подобный трюк.
function findpath (curr, to, path, visited)
path = path or {}
visited = visited or {}
Если аргументы path и/или visited не заданы, то есть они nil, то заводятся умолчальные пустые таблицы вместо непереданных аргументов. Чистенько, красивенько, луа.
Inellok
И некий no value.
Inellok
Есть ещё inf.
Snusmumriken
И некий no value.
Давай ты этими проверками займёшься самостоятельно. Домашнее задание: сидеть и перебирать что получается при разном ковырянии циферок.
Не забудь про math.huge.
И ещё не забудь про 5.5 дней до бана.
Mons
nan легко проверяется
local function is_nan(v) return v ~= v end
Snusmumriken
Я костылял на эту тему, мб в моём luajit чот не то.
Mons
NaN != NaN по определению из ISO'шного double
Snusmumriken
Ну тады не докопал, пасиба, чекну : )
Arslan
@Snusmumriken объясни пж, что такое luajit? В голове не укладывается компилятор для интерпретатора
Snusmumriken
Это такой же интерпретатор как и обычный, только при запуске скрипта делает кучу штук таким образом, что код начинает исполняться в стотыщ раз быстрее.
Snusmumriken
Как раз компилирует горячие последовательности байткода, да и без этого исполняет луа-код быстрее ванильного раза в три.
Arslan
Так он и так быстрый, без оптимизации
Snusmumriken
Он и так быстрый, а с оптимизациями, предельный прирост около 300 раз в сравнении с обычным.
Snusmumriken
В среднем — luajit с включённым JIT быстрее в 20-50 раз. Это довольно много.
Snusmumriken
1. Можно встроить в другую программу luajit вместо lua.
2. Можно из луа дёрнуть
os.execute("luajit %path_to_script%") ))