Serezha
там ничего сложного но человек ты не глупый. если в коллективе с субд работает один два сотрудника никакой орм в том числе навороченная доктрина в последней версии нафиг не нужна.
но там все таки основная часть приложения была именно в сложной админке которая как раз только с доктриной может нормально на лету генерить интерфейс
Serezha
и конечно на больших обьемах все начинает тормозить и лагать
Andrey
да да. фабиен сделал всем "подарок" своими генераторами. Потом говоришь хочу - так, разраб отвечает - нельзя, есть ограничения.
Snusmumriken
Что это за админка такая, где только с доктриной можно на лету генерить интерфейс? Вы что, пытались выгружать в неё миллиарды пользователей и их данные, или что-то такое?
Serezha
но в то время я не знал про такие вещи хотя уже оффтоп пошел https://habr.com/ru/company/lamoda/blog/455571/
Andrey
да про симфоню речь
Snusmumriken
Ужас какой. В самом скл межпрочим тоже есть курсоры, я не понимаю что мешало бегать теми же курсорами по бд для админки. Или запрашивать только узкий набор данных, например по нескольким буковкам.
Serezha
на самом деле когда ты бекендер то админки оч сильно выручают
Snusmumriken
Да я в курсе, я выгружал в админку миллионы логов в форматированном виде. Аналогами курсора, на лету, луями. Типа кинул запрос на обработку и смотришь в реальном времени из админки как разные машины обрабатывают разные части этого запроса.
Andrey
слухайте, вот я вчера на луа придумал как сделать множественное наследование, вообще все круто - за исключением require из модуля из соседней папки. здесь они не доработали на мой взгляд
Snusmumriken
Ну, множественное наследование это типа такого: local superclass1 = {} local superclass2 = {} local superclass3 = {} local child = {} -- их порядок определяет приоритет данного суперкласса child.supers = {superclass1, superclass2, superclass3} function child:__index(key) if child[key] then return child[key] end for i = 1, #child.supers do local v = child.supers[i] if v[key] then return v[key] end end end function child:new(x, y, z) self = setmetatable({}, self) ... -- можно вызывать методы конкретных суперов -- по индексу приоритета self.supers[2].foo(self, x, y, z) return self end Но зачем оно нужно? Схожего поведения можно достичь миксинами, когда мы тупо мерджим таблички.
vvzvlad
Ставлю на невозможность относительных путей без модификации path
Snusmumriken
Ещё можно переопределить require, тогда все возможно.
Snusmumriken
Loadstring никто не отменял.
vvzvlad
Лишний нетривиальный геморрой
vvzvlad
А никто ещё не написал свою require?
Snusmumriken
Я писал, на работе, чтобы грузить из сетевой папки гита для данной конкретной категории машины.
Snusmumriken
Ну, там разбито по категориям. Генерируем путь из корня, имени пользователя и категории машины, лоадстрингаем, если не реквайрится - цепляем старым реквайр из внутренностей базы. Чот такое. Ах да, в таком виде оно ещё может работать в зависимости от того, кто сделал запрос. В той сетевой папке лежат рабочие копии гита разработчиков, поэтому если убрать кеширование, то данная операция отработает под скриптами конкретного разработчика, очень удобно, тестируешь свои штуки и не мешаешь остальным.
vvzvlad
Ну, в смысле, более дружелюбный к пользователям
Snusmumriken
Хмм. Надо подумать.
vvzvlad
Как минимум, с относительными путями
vvzvlad
Как максимум, с интеграцией с luarocks
Pavel
Вот думал хоть здесь про симфони не будут вспоминать. Убегаешь от пыха а он находит тебя в других местах. По поводу орм - дело не только в запросах. Просто тебе внезапно говорят что у нас БД другая и тебе срочно надо с мускула на постгре или еще куда то перейти. орм типа гарантирует это безболезненно но на самом деле любая орм на пыхе - лютое г. Очень сложно разобраться где жрется память и время. Ну и второй аспект - можно набирать программеров которые про sql слыхом не слыхивали. И еще там всякие автоиндексации, перенастройка названий колонок итд. Но тупит и жрет память по определению.
1) вот часто у вас работающий проект базу менял? у меня не было ни разу. а знакомых пару раз. и ни разу при этом это не проходило безболезненно. всегда приходилось и миграцию накатить. и индексы самому еще раз пересоздать. и какой нить автоинкремент отваливается. то еще что нить несовместимое всплывает. такое работает на маленьких проектах, но у них и вопрос - нафига менять вообще? если в принципе хоть на плоских файлах делай. либо когда вы пилите скажем фреймворк для разных задач. и от задачи к задаче используете разные хранилища…. 2) я бы не стал на хайлоад-бек нанимать прогеров, не знакомых с sql 3) ОРМ на любом языке жопа. у пыхи хоть ясно что со статик-кешем. он живет только в рамках запроса. а в какой нить джава, когда объект закешен…или наоборот постоянно мимо еша берется…. 4) переиндексацию делать автоматом при деплое? потому что Вася решил колоночку переименовать? ну такой себе путь….. кладущий прод на обе лопатки, и ведущий к адовейшим потерям
Mark ☢️
1) вот часто у вас работающий проект базу менял? у меня не было ни разу. а знакомых пару раз. и ни разу при этом это не проходило безболезненно. всегда приходилось и миграцию накатить. и индексы самому еще раз пересоздать. и какой нить автоинкремент отваливается. то еще что нить несовместимое всплывает. такое работает на маленьких проектах, но у них и вопрос - нафига менять вообще? если в принципе хоть на плоских файлах делай. либо когда вы пилите скажем фреймворк для разных задач. и от задачи к задаче используете разные хранилища…. 2) я бы не стал на хайлоад-бек нанимать прогеров, не знакомых с sql 3) ОРМ на любом языке жопа. у пыхи хоть ясно что со статик-кешем. он живет только в рамках запроса. а в какой нить джава, когда объект закешен…или наоборот постоянно мимо еша берется…. 4) переиндексацию делать автоматом при деплое? потому что Вася решил колоночку переименовать? ну такой себе путь….. кладущий прод на обе лопатки, и ведущий к адовейшим потерям
Ппкс
Anonymous
Ищу луа разработчика для создания игрового сервера ГТА МТА. 80000 руб. в месяц
Lucky
Что-то маловато сулите. Норм кодеры за 200к.
Pavel
вок кстати пример кодера, который воспользуется ORM и может не знать sql
Snusmumriken
Но кстати за скриптование сампа вроде норм.
Egor
Доброе утро. https://pastebin.com/SKGjeaA2 Как правильно написать, чтобы из TestClass:calc() были доступны self ? как вариант делать return TestClass:calc(self) но такое себе не?
Lucky
На =)
https://habr.com/ru/post/346892/
Egor
https://habr.com/ru/post/346892/
я его и перечитал
Egor
В луа правильно ли делать так: function myFn() if myVar == 0 then -- делать что-то затем прервать return true end -- делать другое end ?
mva
обычно такое используется для обратного
mva
в теле функции делается то, что функция должна делать, а в условии с return'ом - условие для того чтобы этого не делать
mva
но тебе никто не запрещает делать как хочешь
Snusmumriken
В луа правильно ли делать так: function myFn() if myVar == 0 then -- делать что-то затем прервать return true end -- делать другое end ?
Ага. function foo(msg) local data, err = json.decode(msg) if not data then return nil, "Json decode error: " .. tostring(err) end if not data.foo then return nil, "Field foo expected" end -- после всех проверок что нам -- прислали валидные данные — -- делаем всякие штуки return data.foo + data.bar end
Andrey
local A={} local B={} setmetatable(B,{__index=A}) A.foo={} B.foo={} A.foo.bar={} B.foo.bar={} A.foo.bar.bar1="a1" A.foo.bar.bar2="a2" B.foo.bar.bar1="b1" print (B.foo.bar.bar1) print (B.foo.bar.bar2) второй принт выдает nil а как сделать так что бы искал в A ?
Andrey
local A={} local B={} setmetatable(B,{__index=A}) A.foo={} B.foo={} A.foo.bar={} B.foo.bar={} A.foo.bar.bar1="a1" A.foo.bar.bar2="a2" B.foo.bar.bar1="b1" print (B.foo.bar.bar1) --b1 print (B.foo.bar.bar2) --nil A.foobarbar1="a1" A.foobarbar2="a2" B.foobarbar1="b1" print (B.foobarbar1) --b1 print (B.foobarbar2) --a2
🐅🤦‍♂️
В луа правильно ли делать так: function myFn() if myVar == 0 then -- делать что-то затем прервать return true end -- делать другое end ?
Мне кажется, что в длинных и сложных функциях лучше делать одну точку возврата, в самом конце. Иначе сложнее понимать код.
Andrey
Мне кажется, что в длинных и сложных функциях лучше делать одну точку возврата, в самом конце. Иначе сложнее понимать код.
оно ругается если после ретурна есть неиспользуемый код. даже если в if ... then ... return else .. return end blablacode кстати вопрос - как для отладки правильно делать die ? я обычно ставлю error()
Snusmumriken
Мне кажется, что в длинных и сложных функциях лучше делать одну точку возврата, в самом конце. Иначе сложнее понимать код.
Если все время писать от противного, ретурня ошибки в первой половине, а во второй - писать код для "лучшего случая" - оно более чем нормально читается, хоть и не супер чисто выглядит.
Snusmumriken
Можно было бы для чистоты кода завернуть всё в pcall, но это кошмарно бьёт по производительности.
Snusmumriken
Но лично снус пришел к написанию от противного, и возврату nil, "текст ошибки".
Snusmumriken
Вот чего мне таки не хватает в луях, это аналога ассерта типа: check(expr, errortext), чтобы оно автоматом выводило из текущей функции с false, errortext при несоблюдении expr. Можно было бы гораздо компактнее упаковывать все проверки. В голанге совсем недавно такое ввели ровно для этих случаев.
Mark ☢️
Мне кажется, что в длинных и сложных функциях лучше делать одну точку возврата, в самом конце. Иначе сложнее понимать код.
На самом деле надо ограничивать для себя уровни вложенности. Никак не более 2 в функции
Snusmumriken
оно ругается если после ретурна есть неиспользуемый код. даже если в if ... then ... return else .. return end blablacode кстати вопрос - как для отладки правильно делать die ? я обычно ставлю error()
Просто ставь ретурн последним в данном чанке кода. Это нормально что ругается, ибо если после ретурна в данном чанке что-то есть, оно точно не выполниться. А вдруг ты решишь поставить после этого ретурна ещё один ретурн, что они должно делать в этом случае?
Snusmumriken
На самом деле надо ограничивать для себя уровни вложенности. Никак не более 2 в функции
Вот мое "написание от противного" как раз схлопывает вложенность, да.
Mark ☢️
Вот мое "написание от противного" как раз схлопывает вложенность, да.
Тут есть прекол. Перед выходом часто надо динициализацию делать. Поэтому не ретурн, а гото енд
Mark ☢️
Но это в сях. На луе обычно не требуется. Хотя закрывать файлы....
Mark ☢️
А то гц хз когда их закроет
Snusmumriken
Хотя хендлеры файлов, разумеется, лучше завершать.
Mark ☢️
if bla then self:close() return nil, "bla" end Ооп выручает.
А потом рефакторишь и превед. Лучше динициализацию в одном месте хранить, а не размазывать по функции с кучей копипаст
Snusmumriken
Ну, self:close оно и в Африке self:close
Snusmumriken
Можно ещё оформить close как функцию, которая принимает первым аргументом текст, и возвращает nil и этот текст, чтобы такой: return self:close(errortext)
Snusmumriken
Но это слегка снижает гибкость.
Snusmumriken
local A={} local B={} setmetatable(B,{__index=A}) A.foo={} B.foo={} A.foo.bar={} B.foo.bar={} A.foo.bar.bar1="a1" A.foo.bar.bar2="a2" B.foo.bar.bar1="b1" print (B.foo.bar.bar1) print (B.foo.bar.bar2) второй принт выдает nil а как сделать так что бы искал в A ?
Таблички по __index просто смотрят, есть ли в другой табличке другой такой ключ, и НЕ делают этого если он там такой был. local t1 = {foo = {e = 1}} local t2 = {foo = {}} setmetatable(t2, {__index = t1}) local foo = t2.foo В t2 нашёлся такой ключ, есть такая таблица, она не имеет никакого отношения к такой же таблице в t1, она не знает что в t1 есть такая же. Но их тоже можно связать. setmetatable(t2.foo, {__index = t1.foo}) print(t2.foo.e) --> 1 Это порождает немножко больше связей, но по крайней мере будет искать ключи. Для автоматики, стоит писать функцию, которая будет рекурсивно связывать все таблицы внутри корневых. Но с одной стороны, это муторно, с другой — не особо нужно.
Yuriy
init.lua lua ищет по умолчанию если прописываешь папку ка кreuqire помоему. но не все LVM это делают
Yuriy
я всегда прописываю рукчками сначала закидываю все в init.lua и потом оттуда уже инициализирую
Yuriy
типа mydir/mymodule/init.lua и в этом init.lua уже делаю local mymodule = { file1InmymoduleDir = require "mydir.mymodule.file1InMyModuleDir", file2InmymoduleDir = require "mydir.mymodule.file2InMyModuleDir" } А в main.lua уже экспортирую mymodule mymodule = "mydir.mymodule.init"
Mark ☢️
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=891541
Mark ☢️
Ubuntu 18.04 LTS
Snusmumriken
А хз ))
Snusmumriken
Напиши, это три строчки
Mark ☢️
Напиши, это три строчки
https://stevedonovan.github.io/Penlight/api/libraries/pl.tablex.html#size
Mark ☢️
стейк оверфлоу
Mark ☢️
но я не хотел. я старался.
Mark ☢️
А хз ))
запили антиспам бота типа терминатора
Snusmumriken
Уже предлагал @AlexFails, но его чот нет в наличии
Snusmumriken
Народ, вы откуда?