mva
что-то я тут пытаюсь придумать как бы в resty ловить трейсбек не только в лог, но и при желании срендерить его в выхлопе, но что-то пока фигово выходит >_>
Roman
я делал такую штуку, может подскажу что
mva
Рома ну, мне бы посмотреть код, впечатлиться и по мотивам написать...
А то я тут пока извращениями с xpcall, debug.getinfo() и т.п. занимаюсь :)
Roman
ну так, верный путь
Roman
xpcall main, catch - главный луп
catch = (e) ->
i = 1
t = 0
trace = {}
import getinfo from debug
while true
i += 1
info = getinfo i
if i == 2
space = e\find ' '
info.err = e\sub space + 1
import func from info
t += 1
trace[t] = info
break if func == main
и тут делай со стрейсом что хочешь
Roman
я не помню уже как оно работает, но работало
Roman
сейчас меня ещё одна идейка посетила
есть куча тупых вконтактов-фейсбуков-скайпов-вайберов-вотсапов-телеграмов и тычячи их.
зачем столько - никогда не понимал.
где есть подсветка синтаксиса?? нигде!
(гитхаб это не мессенджер)
mva
> import from
mva
внимание: вас укусил питон! срочно пройдите в отсек дезинфекции
mva
:)
Roman
чсх, питон в глаза не видел
Roman
мне нравится так писать, красивее чем a = b.a
mva
Temirgali
Андрей
Эмм...
P. S. Как и нафига? :)
Snusmumriken
То чем можно вдохновляться: https://bitbucket.org/rude/love/src/10f58e78bbfd82b681a45aeaf1177a765726bb31/src/scripts/boot.lua?at=default&fileviewer=file-view-default
Скрипт запуска love-проектов.
Snusmumriken
Там в конце нормальный дебаггер с полным стактрейсом.
mva
а какие функции "напатчил"?
ну, для начала научил его собираться с системными кутями, без их патчинга и без сборки своих и статической линковки к ним. Потом сделал чтобы балуны были по ширине текста, а не полтора пикселя (утрировано). Ну и так по мелочам.
Пытаюсь, вот, ещё от gtk-диалога избавиться :)
Roman
Snusmumriken
Roman
зачем первая и вторая?
Roman
чего не одна?
Snusmumriken
Первый позволяет безопасно выполнять функцию с аргументами, второй - функцию без аргументов, зато с хендлером ошибок.
Snusmumriken
Я их объединю, не бойся.
Roman
предвкушаю!
Snusmumriken
Внутри хендлера можно вызвать debug.stacktrace() и получить полный стектрейс, выдать его как сообщение. А не только куцая ошибка, как в обычном pcall.
Snusmumriken
У меня на работе из-за этого много проблем: есть ошибка, а где она появилась, в каком из десятка разных локальных копий гита - неизвестно. Надо переделывать.
Roman
может кто-нибудь знает как на андроиде трафик перехватывать со включенным vpn? весь вечер ковыряюсь
Alejandro Jeditobe
Вирос нибось пишешь
Roman
я такими вещами не занимаюсь
mva
mva
в 5.2+ и в luajit аргументы можно передать после хендлера
Светомеч
Светомеч
https://highlightjs.org
>174 languages
Светомеч
Это вроде там юзается
ㅤ
Да, Discord поддерживает Markdown, и можно сделать
```lua
......
Tverd
"разработка визуальной web-части проекта: сам сайт, личный кабинет, различные api и т.п." - веб на луа? фронт? )
Snusmumriken
Хех, они послушали мой совет : )
https://hh.ru/vacancy/20519107?query=lua
Tverd
какой совет? они и искали человека... ))
Snusmumriken
В этой группе
mva
mva
у меня, вот, j4f пару проектов на ngx_lua+ngx_postgres
Snusmumriken
Ну типа при запуске типа такого:
lua c:/scripts/scr.lua -path "c:/filepath"
Аргументы находятся в таблице arg.
for k, v in pairs(arg) do print(k, v) end
> 0 c:/scripts/scr.lua
> 1 -path
> 2 "c:/filepath"
Оно может слегка отличаться, я не помню точно, нулевой ли аргумент - путь до самого скрипта. Но суть та же.
Snusmumriken
А, да, легко. Я свой сжиматель файлов тоже с интерфейсом командной строки пилю.
Если будешь выводить результат программы в io.write - то сможешь с линуксом взаимодействовать, как с обычной юникс-тулзой, только запускаемой через lua:
cat lua /home/scr.lua /texture.png > dev/null
Snusmumriken
Или что-то такое мб поможет: https://github.com/LuaDist/libpng
Snusmumriken
И обрезкой мышкой картинки, да.
Можно всё, но это будет долго. Урезай количество фич, оставляй необходимое.
Snusmumriken
Тише, ты в общем чате. Не спамь узкоспециализированной фигнёй в тысячи сообщений. Давай или в ЛС переходи, или оформляй длинные законченные посты.
Roman
Есть странная проблема: гружу модуль таким ненормальным образом:
f = io.open('path', 'r')
content = f:read('*a')
-- нахожу кое что в content и меняю связанную глобальную вариаблю
fn = loadstring content
и все неплохо, но ошибки, производящиеся этим файлом выглядят непригодно, не указывают на файл.
Что посоветуете?
можно читать файл и потом loadfile, но это значит, что файл 2 раза открывается, не оптимально
Snusmumriken
Есть странная проблема: гружу модуль таким ненормальным образом:
f = io.open('path', 'r')
content = f:read('*a')
-- нахожу кое что в content и меняю связанную глобальную вариаблю
fn = loadstring content
и все неплохо, но ошибки, производящиеся этим файлом выглядят непригодно, не указывают на файл.
Что посоветуете?
можно читать файл и потом loadfile, но это значит, что файл 2 раза открывается, не оптимально
За счёт того что это loadstring, ошибки не будут указывать на файл. Там в debug.getinfo().source не путь до файла сидит, а сама строка, с которой грузили код. Сам ровно прошлой ночью с этим возился, но тут такое дело.
У тебя есть целых два варианта решения задачи, и оба - суть "сделаем программирование нормальным":
а) вытаскивать новую глобальную переменную из модуля через return var в конце модуля
newglobal = require'module'
б) Использовать минимум глобальных вариаблей. Модуль должен возвращать объект, не создавать и не модифицировать ничего глобального, и сам - реквайрить минимум другой фигни. В идеальных условиях, всё приложение - это всего лишь один глобальный объект, который является менеджером для всех остальных объектов. Ну, это идеальные условия.
В моих игрулях, таким объектом является объект gamestate, который суть конечный автомат с набором состояний: разные менюшки (тоже конечные автоматы, на каждое игровое меню), игровой процесс (который тоже конечный автомат но в квадрате: для "директора" игрового процесса и для всяких пауз/внутриигровых меню) и всякая такая лабуда.
В микросервисах, таким объектом является основной объект, с методами init/update, и общая схема проекта выглядит примерно так:
main_class = Class()
...
-- описываем основной класс
...
while true do
main_class:update()
sleep(n)
end
Ах да, если одна библиотека используется сразу кучей модулей, я обычно передаю её модулям из корневого объекта в процессе инициализации. Ну, чтобы только в одном месте заменять эту библиотеку, в случае чего (изменение либы/путей).
Roman
Суть в ленивой загрузке, рекурсивно обходятся вложенные папки и файлы по именам становятся глобальными классами, а потом при обращении к __index лениво загружаются. И родительские классы тоже грузятся лениво. И получается вынос мозга. Видимо, тут open и затем loadfile необходимое зло. А вдруг можно самому подписать loadstring'у его файл? Гуглить это бесполезно, вопрошаю гуру!
Snusmumriken
Ты хочешь ленивости? Зачем тебе? Микрухи что ли, для экономии памяти?
Мб просто загрузчик всей фигни сделаешь?
Не надо извращений. Если у тебя есть батон хлеба и мамины спицы, ты конечно же можешь сделать троллейбус. Но подобные штуки имхо лучше делать по-человечески.
Например, тот же загрузчик, который через lfs получает список файлов/директорий, обходит их, ищет lua-файлы и реквайрит их типа:
require'folder1.folder2.script'
Это относительно человеческий способ.
Полагаю, в глобальной переменной хранится путь "текущей папки"?
void *
Snusmumriken
Да, кстати, ребят, хочу поздравить вас всех с одним замечательным событием!
Ровно двадцать три года назад, на свет появился один замечательный человек, которому мы все благодарны за его неоценимую помощь и восхитительные человеческие качества! В телеграме, этот человек известен как @Snusmumriken, прошу любить и жаловать!
Ехехехехе.
void *
Поздравляю :)
Snusmumriken
О да, передам ему, будет рад : )
ㅤ
И от меня передай себе поздравления.
Snusmumriken
Письмо напишу, секунду
Roman
Я тут хотел восхвалить ленивость и поведать о том, сколько у неё преимуществ, ладно, с днем рождения, великих свершений Ж)
Snusmumriken
Snusmumriken
Я тут хотел восхвалить ленивость и поведать о том, сколько у неё преимуществ, ладно, с днем рождения, великих свершений Ж)
Ну, сама по себе ленивость - хороша при вычислениях.
x = fast_function() or slow_function() - это гораздо лучше чем
a, b = fast_function(), slow_function()
x = a or b
Но при require, не вижу особого смысла: вызывается один раз. Если что, require кеширует результат, поэтому если в нескольких модулях require'нуть один и тот же модуль, он будет загружен только один раз, а второй - подтянется из кеша. Плюс сложнее отслеживать ошибки: синтаксические оно выведет сразу, по крайней мере. А с loadstring - только когда модуль будет заюзан, то есть, возможно - никогда.
Тут может быть некоторый смысл в том случае, если у тебя очень мало памяти, и весь проект в ней не помещается. Например, если ты пишешь веб-сервер с загрузчиками/шаблонизаторами на ESP (микроконтроллер, довольно сомнительная затея, но некоторым нравится), то да, оказывается эффективнее загружать модули через dofile (ибо не кеширует), и выгружать модули когда те не нужны вот прямщас.
Snusmumriken
Ну, например, когда я определяю в коллайдере, касаются ли друг друга два объекта сложной формы, я сначала проверяю на AABB (это очень быстро, сравнить четыре точки описывающего прямоугольника объектов), а потом, если AABB прокатил - использую сложные коллизионные функции для уточнения. Это тоже образец оптимизирующей "ленивости".
Roman
Ладно, восхвалю
речь о openresty, раз уже есть сайтец, приходится держать код в строжайшей крутости
1) Да, ощутимо лучше реагирует, когда за один запрос грузится 1 контроллер и пара моделей, а не все что есть
2) Можно натворить дел, например, с помощью гит конфликтов, когда реквайр будет валиться.
А с ленивой загрузкой исправляй себе по одному и оно будет работать.
3) Ключевое! Когда заведомо не знаешь, какой класс от какого наследуется, require не в том порядке - все, кранты. С ленивой - цепочка распутывается сама по себе
4) Когда при объвлении модели нужно делать запросы. Объявляешь класс User, и он давай у базы данных спрашивать колонки, типы колонок, первичный ключ, я даже до такого дошел, что из базы берутся кастомные ограничения для валидаций, вроде length(login) > 3 и length(password) > 5. Тогда при каждом запросе в базу пойдут несколько запросов на каждый файл, когда оно все сразу не надо.
Для тру модулей require конечно, для MVC'шных вещей - ленивость.
Roman
что такое шаблонизатор на ESP? не гуглится
Snusmumriken
OpenResty кеширует прям байткод всей виртуальной машины на момент первого запуска, и гоняет его раз за разом. Получается сверхбыстро. Правда, всякие math.random перестают работать: застревают на моменте первого запуска, как и os.time(). Не парься с загрузкой, она будет мгновенна когда надо. Разрабатывай без кеширования, на прод выдавай с кешированием.
Snusmumriken
Когда не знаешь, какой класс от какого наследуется.. Вот это странно.
Модуль любого наследника начинается с require родителя. Не важно в каком порядке вызывать: родитель будет вызван до любого наследования.
Roman
Разработчика волнует девелопмент, а прод с resty - молниеносен по дефолту
Roman
> Модуль любого наследника начинается с require родителя.
мне нравится такое:
class SubController extends ParentController
-- code
и никаких реквайров
Snusmumriken
На жаве?
Roman
на мунскрипте
Roman
ну правда долго очень эту одну строчку писать на луа
Snusmumriken
Стопэ, все классы висят в глобальном пространстве?
Roman
Ну да, потом откуда захочешь - оттуда и используй
Roman
Post\all! допустим будет в куче контроллеров, везде делать require 'models.post' чтоли?
Snusmumriken
Ой мама. Вот поэтому я и не люблю такое.
Карочи, по-человечески это делается так:
local ParentContoller = require'PController'
local class SubController extends ParentController
... code ...
return SubController
Roman
возвращается оно автоматом
Snusmumriken
В мунскрипте можно делать pure-lua-вставки, насколько я знаю.
Snusmumriken
Но тем не менее, очень советую держать всё содержимое модулей внутри модулей, с одним возвратом содержимого модуля.
Если тебе оно понадобится в нескольких местах - сделаешь лишний require.
Так оказывается гораздо меньше зависимостей, в которых ты запутаешься, как только проект сколько-нибудь разрастётся.