
Group Butler [beta]
26.04.2017
21:04:32
Добро пожаловать в чат pro.lua, Alexandr! Ознакомься с правилами чата (в описании и прикрепленном сообщении), и присоединяйся к обсуждению.

Vlad
26.04.2017
22:01:33
или просто кто чепочем растолкует типа дэбил, ничерта не знаешь, это изучай, не понял повторить пока не поймешь, тут удели особое внимание, тут посмотри там почитай и тд

Philipp
27.04.2017
06:09:43

Google

Alexandr
27.04.2017
06:41:03
Доброго времени суток, посоветуйте докладчиков по Lua на DevConf'17 https://devconf.ru/ru/offers

Group Butler [beta]
27.04.2017
08:29:16
Добро пожаловать в чат pro.lua, Petr! Ознакомься с правилами чата (в описании и прикрепленном сообщении), и присоединяйся к обсуждению.

Yuriy
27.04.2017
18:43:44
всем доброго времени суток
Такой вопрос
Есть таблица
local settings= {
name="foo",
surname="fam"
}
Есть текст (многолайновая строка)
Которая содержит в себе несколько полей
name={settings.name}
surname={settings.surname}
При парсинге я получаю строки
settings.name
и settings.surname
Хочу заменить их на реальные значения таблицы
Пытаюст это сделать через loadstring(str)
Где str="settings.name" например
что-то типа
"name="..loadstring(str)
Lua ругается. [string "settings.name"]:1: '=' expected near '<eof>'
Как я понимаю loadstring от меня ждет не имени переменной а полноценного выражения.
Собственно вопрос. Как получить именно имя переменной?

Vadim
27.04.2017
18:46:05
предлагаю вместо изобретения колеса использовать готовый темплейтер

Yuriy
27.04.2017
18:46:38
Например?
Хотя нагуглить то я нагуглю. Ну просто если темплейтеры это делают, хочется понимать как

Alexey
27.04.2017
18:55:26

Vadim
27.04.2017
18:56:45
Мне немного не понятен твой пример, что ты в последнем шаге хочешь с loadstring. Вот насколько я понял, на Lua5.3 (lua demo):
settings ={}
settings.name="!@#$"
settings.surname = "my fam!"
load("print(settings.surname)")()
--или заморочиться так:
var = load("return settings.surname")()
print( var )
Но то же самое и с gsub, работая со строкой проделать можно

Рома
27.04.2017
18:58:42
хей, eval == evil

Yuriy
27.04.2017
18:59:24
Как ты правильно увидел я делю некий шаблонизатор
Тектс хранит шаблоны ("settings.surname")
Шаблон по сути это адрес переменной в которой лежит необходимое значение
Вот это значение я и хочу достать
То есть на вход подается шаблон - текст с чанками и таблица, содержащая значения этих чанков
На выходе должен получиться текст в которм чанки заменены реальными значениями

Vadim
27.04.2017
18:59:50
Потому и string.gsub!

Yuriy
27.04.2017
19:01:15
ну да... Я понимаю
Я ею и делаю вот таким образом примерно
local line=string.gsub(str,'%{.+%}',loadstring("settings.surname"))
толкьо инетрпретатор ругается как раз ошибкой которрую я запостил выше

Vadim
27.04.2017
19:02:46
Да, потому что в лоадстринге у тебя не законченный кусок кода. относись к нему как к файлу. Поэтому я во втором примере добавил "return settings.surname"

Google

Vadim
27.04.2017
19:03:43
а да, и loadstring запустить надо ()
но блин, всё ещё несведомая ЛУтАющая тарелка получается.
Случайно кнопку зажал, не обращайте внимания...

Yuriy
27.04.2017
19:07:17
Тем не менее
local settings={name="foo"}
local code="settings.name"
local line=string.gsub(str,'%{.+%}',loadstring("return "..code)())
lua: [string "return settings.name"]:1: attempt to index global 'settings' (a nil value)

Vadim
27.04.2017
19:07:51
Да, доступа к локальным переменным нет по-моему.

Yuriy
27.04.2017
19:08:22
то есть таким способом яне достучусь до необходимо мне таблицы как я понимаю...
потому что значение возвращается из строки, которая не видит перемееных в данном файле...

Vadim
27.04.2017
19:09:32
Нет. Только самому распарсивать эти ваши %username% и подставлять

Yuriy
27.04.2017
19:10:05
Да распарсить то оно распарсивается.

Vadim
27.04.2017
19:10:13
либо пробрасывать таблицу в окружение loadstring. (sandbox из 5.1)

Yuriy
27.04.2017
19:14:59
библиотека templet сделал все за меня.
Но спасибо в любом случае за разъяснение.

Vadim
27.04.2017
19:24:45
Я синтаксис string.gsub подсмотрел, всё очевидно, Ватсон (такого не делал просто :) ):
textchunk = "And thus God spoke to settings.name and told him to settings.action"
settings = {}
settings.name = "spy"
settings.action = "respond"
print(string.gsub(textchunk, "settings%.([%w%d]+)", settings))
То есть он захватывает вторую часть от settings.(name/action) и подставляет ключ в таблицу: settings["name"] и settings["action"]
Если ключ не найден, подмены не происходит


Yuriy
27.04.2017
19:28:29
хм.. Спасибо добр человек
Если что я через templet сделал уже
Получилось что то вроде этого
local templet = require("templet")
local str=[[name=${settings[1].name}
surname=${settings[2].surname}]]
local template=templet.loadstring(str)
local settings={{name="foo"},{surname="fam"}}
local newSettings={settings=settings}
print(template(newSettings))
Всем привет!
Еще вопрос по поводу чанков
Из предыдущего разговора
gsub если ему подставить таблицу будет пробегатьпо каждому ключу
И если название ключа матчится выражению то строка заменяется значением ключа
То есть
loca myTable={name="vasya"}
local str="name={name}"
print(string.gsub(str,"{(%w+)}",myTable)
Вывод будет
name=vasya
подсткажите пжлст по поводу вложенности.
Пример у еня есть таблица
local myTable={persons={{name="vasya"},{name="petya"}}}
соответсвенно лежат они как
myTable.persons[i].name
но
local str="name={persons[1].name}"
print(string.gsub(str,"{(%w+)}",myTable))
В данном случае ничего не сделает
как я понимаю gsub пробегает толкьо по первому ключу
То есть во вложенные таблицы gsub не смотрит
Какие ест ьварианты проблежаться по вложенностям? мб кто реализовывал?


Snusmumriken
28.04.2017
08:34:57
Пихаешь в gsub функцию, которая пробегает по ключам как тебе нужно.
Допустим, примерно так:
local function uuid()
local template ='xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'
return template:gsub('[xy]', function (c)
local v = (c == 'x') and random(0, 0xf) or random(8, 0xb)
return ('%x'):format(v)
end)
end
Тут функция, которая принимает и возвращает переработанный символ.
Только вместо преобразования буквы в шестнадцатиричку, функция может произвольно пробегать по ключам таблички, и делать вообще любую ересь, хоть открывать веб-сервер с эвент-лупом, возвращая из функции строку, в которой все слова "Хой" заменены на что-нибудь принятое от клиента.

Yuriy
28.04.2017
08:41:35
Аха
Кстати функция обязательно анонимная должна быть?
Или я могу подпихнуть свою с ее какими либо входными параметрами?

Snusmumriken
28.04.2017
08:42:20
Свою. Только первый аргумент - строка (собсно, то что выдралось из оригинала по шаблону), и выходная фигня тоже должна быть строкой.

Google

Yuriy
28.04.2017
08:43:10
оке
То есть 2,3,4 она сожрет как ни в чем не бывало
Это хорошо. спасибо.

Snusmumriken
28.04.2017
08:43:55
Но сам gsub будет пихать только одно значение. Или, кстати, может быть несколько (допустим, ещё порядковый номер замены или сдвиг позиции текущей замены), я не помню точно.

Yuriy
28.04.2017
08:44:42
ок. спасбо. Буду делать .В обещм понятно
Пробежаться по таблице
Получить путь до переменной
Сравнить со строкой
Заменить

Snusmumriken
28.04.2017
08:45:46
В луа, без анонимных функций нельзя сделать разве что итераторы. И то, кстати, можно, но это будет извращение.
Всё остальное может быть произвольным, хотя с лямбдами бывает удобнее. Я, вон, вообще мутил генератор лямбд.
Преобразует 'x => x + 10' в function(x) return x + 10 end
Зачем? Потому что мне лень писать кучу длинных слов. Сама концепция стрелочных функций сворована из жаваскрипта. Если код перед запуском пихать в препроцессор, то можно нехило расширять синтаксис без подобных манипуляций со строками, но такое тоже ничего так.
Кстати, вот тебе пример loadstring'а.

Рома
28.04.2017
09:03:06
А я нашел математическую задачку в книге "Хайнойская башня", и захотелось бенчмарки сделать на moonscript, coffee и ruby, сахарки чтобы объем кода тоже был критерием, кому любопытно что за сколько?

Плюшка
28.04.2017
09:03:22
Мне

Рома
28.04.2017
09:04:10
Итак, lua: 1.24сек, js: 5.43сек, ruby: 43.9сек

Snusmumriken
28.04.2017
09:04:26
Хех, победит moonscript, если luajit в качестве виртуалки. Проиграет руби потому что нет jit.

Плюшка
28.04.2017
09:04:29
Неудивительно)

Snusmumriken
28.04.2017
09:04:32
А, ну типа того.
У тебя v8 в качестве двигла js?

Alex Фэils?︙
28.04.2017
09:05:25
На си++ написать, и у него время выполнения будет 0
(Потому что автор упоролся, и решил задачу на этапе компиляции)

Snusmumriken
28.04.2017
09:05:47
Смотря как. Истинные гуру с++ могут написать так, что бесконечности будет мало.
Рекурсивные функции нельзя решить на этапе компиляции, вроде. Хоть template и работает на этапе компиляции, но при рекурсии и время исполнения будет не 0.

Рома
28.04.2017
09:11:28
код на мунскрипте самый компактный, на coffee самый длинный, потому что там нет параллельного присваивания
код полностью идентичнен

Google

Рома
28.04.2017
09:11:29
это 26 дисков, в оригинале 64 диска, и когда все передвинутся - будет конец света, но конца света очень долго ждать
модуль вайфая в линухе просто жесть, вырубается когда хочет
эм, c++ что-то решает на этапе компиляции? в него хаскел добавили в новых версиях разве?

Плюшка
28.04.2017
09:15:06

Snusmumriken
28.04.2017
09:15:06
> код на мунскрипте самый компактный
Трансформируй код мунскрипта в луа, и ты увидишь самый длинный в мире код. Там реально - очень, очень много замен.
Меня слегка раздражает куча препроцессоров перед исполнением. Это как less над css, которое не делает ничего кроме парсинга и автозамен, каждый раз когда исполняется код (хотя мб можно закешировать).
Это как будто мы транслируем цепочку из десяти языков, один в другой. Нехило замедляет, кстати, и требует встраивания кучи препроцессоров.

Рома
28.04.2017
09:15:54
зря ты так
нормальный код

Admin
ERROR: S client not available

Snusmumriken
28.04.2017
09:16:09
Да, с++ умеет многое вычислять на этапе компиляции, и использовать результаты. Скомпилированный код занимает чуть больше пространства, но какое-нибудь вычисление занимающее 100500 суток начинает занимать близкое к нулю значение.

Рома
28.04.2017
09:17:04
да, именно он

Snusmumriken
28.04.2017
09:17:30
А, ну тут может быть, потому что нет ООП/лямбд и прочего синтаксиса. Обычные функции занимают почти столько же пространства.

Рома
28.04.2017
09:18:26
тью, конечно если пишешь class в мунскрипте, в lua будет намного больше строчек
в общем не хочу спорить, лишнего moon не делает, только иногда do end добавляет

Alex Фэils?︙
28.04.2017
09:21:35
Есть же constexpr

Snusmumriken
28.04.2017
09:21:43
ООП попробуй замутить, с метаметодами.
В моей жизни, мне действительно понадобился препроцессор в одном месте: либа-надстройка над многопоточностью, где код пихающийся в дочерний поток - строка. В дочерний поток дописывается однострочник с объектом для взаимодействия с родительским и ещё кучей потоков, а так же имя из родительского: между потоками стоит открыть дуплексный именованный канал, который работает по умолчанию и присобачивается к эвент-лупу для взаимодействия потоков, и тут нужно определить имена каналов для входящих-исходящих соединений.

Рома
28.04.2017
09:23:03
setmetatable и getmetatable одинаково одна строка
не понимаю о чем ты

Google

Snusmumriken
28.04.2017
09:23:21
Лучше сурц и скомпиленное скинь на pastebin.com.

Рома
28.04.2017
09:24:08
он не умеет в подсветку

Snusmumriken
28.04.2017
09:24:17
Умеет в подсветку луа, не умеет в мунскрипт. Но это ничего страшного.

Рома
28.04.2017
09:27:19
https://pastebin.com/ShKRDLd1

Snusmumriken
28.04.2017
09:28:46
А, ну это понятно. Прости, я имел ввиду, замутить что-нибудь сложное в мунскрипте с ООП, перегрузками и лямбдами, а потом трансформировать в луа и посмотреть на разницу.

Рома
28.04.2017
09:29:07
пример можешь?

Snusmumriken
28.04.2017
09:29:39
На луа?
Сам не пишу на мунскрипте, придётся что-то переписать.

Рома
28.04.2017
09:29:50
пример того, о чем говоришь
пруф слов

Snusmumriken
28.04.2017
09:30:19
Пруф чего, прости?

Рома
28.04.2017
09:30:47
Так, это не утверждение, что мун лишний код делает, а предположение?
Не понимаю! Это все равно всеми любимый луа! ООП такой же + class, перегрузка - присвоить переменной другое значение, тут лишний код невообразим, лямбда - это анонимная функция? Эти термины из других языков, мне не очень понятны.
это синтаксический сахар, делает синтаксис более удобным, end, function и т.д можно опускать, он по задумке своей не должен лишний код генерировать. Там есть специфические фичи, которые можно использовать, а можно и не использовать

Philipp
28.04.2017
09:38:09
Щас Лёшка затащит


Snusmumriken
28.04.2017
09:43:21
Смотри. Пример с официального сайта.
class Thing
name: "unknown"
class Person extends Thing
say_name: => print "Hello, I am #{@name}!"
with Person!
.name = "MoonScript"
\say_name!
Превращается в (тут можно посмотреть): https://moonscript.org/
На луа, это можно было бы сделать примерно так же:
Thing = {}
Thing.__index = Thing
setmetatable(Thing, {__index = Thing, __call = function(self, name, ...) return setmetatable({__name = name}, self) end})
Person = {}
Person.__index = Person
setmetatable(Person, {__index = Thing, __call = function(self, name, ...) return setmetatable({__name = name}, {__index = self})
function Person:say_name() print(self.__name) end
Ну, длина увеличилась не сильно. Но в сравнении со сгенерированным кодом, тут значительно меньше пространства.
Да, тут есть проблемы с комфортом, но не вижу проблемы написать либу ООП и подключать её отдельно, хоть и без такого синтаксического сахара, как стрелочные функции, например.
Проблема в другом: мунскрипт генерирует огромную кучу кода в каждом файле. Он мог бы дописывать маленькую либу ООП перед каждым файлом, где используется ООП. Это довольно быстро. Но оно предпочитает генерировать на каждый класс огромную портянку всякой фигни.
И отладка этого счастья превращается в что-то похожее на ад и израиль, особенно когда у тебя что-то сложное, каскадно-рекурсивное. Вместо того чтобы копаться в собственном коде, приходится копаться в сгенерированном, что, согласись, является приличной проблемой: ты не знаешь где точно ошибка, ибо интерпретатор указывает на положение в сгенерированном коде, а в сурцах мунскрипта это совсем в другом месте. Дебаггер тут мало помогает, потому что мунскрипт ещё и пихает кучу своих переменных/функций/данных.
И поддерживать сгенерированный мунскриптом код, если нет сурцов, довольно стрёмно.


Рома
28.04.2017
09:49:39
Да, эту проблему подтвержаю, с отладкой, но! Делал отладчик, давно делал, он уже сломался, но починю как будет время. Суть отладчика: с помощью debug библиотеки он собирает всю инфу о файлах и строчках кода и выдает то же самое, но с указателями на мун файлы с мун строчками кода, эта проблема решаема

Snusmumriken
28.04.2017
09:51:13
А если нет мун-файлов? Ты уже всё упаковал, скинул в проект пол года назад, благополучно профукал сурцы мунскрипта и вот, у тебя вылезла ошибка. Тебе придётся разбирать проект полностью заново.
Нет, мне нравится синтаксис и количество сокращений кучи слов.
Я искренне ненавижу писать большое количество слов, для того чтобы делать простые вещи. Да и сложные тоже.
Но я пишу сахарные библиотеки, и это оказывается эффективнее препроцессоров.

Рома
28.04.2017
09:51:43
классы никто не запрещает делать как ты хочешь, можешь свою реализацию сделать и грузить реквайром
а исходники конечно нужно хранить, на то они и исходники