Snusmumriken
Дурацкий способ в большинстве случаев. Снижает читаемость на пустом месте. Хотя смотря где.
Lucky
Единственный довод писать без goto - поддержка Lua 5.1
Snusmumriken
Всё остальное "можно без него, я слышал что низя, мама меня по жопе настучит за использование поэтому вам тоже нельзя" — ну как бы не аргумент. А ещё можно писать асинхронщину без корутин. Можно, но не удобно и крайне не читаемо. Но зачем, если есть мощные и клёвые корутины? Но над гото стоит дамоклов меч религиозного непринятия, да. А над корутинами — нет ))
Lucky
И мне тот кусок кода препод вуза переписывал так, чтоб было без goto. Я до сих пор не понимаю, как этот кусок работает.
Lucky
С goto я написал сам. И это был простой и лаконичный код.
R
Проблема goto в высокоуровневых языках не в самом goto, а в том, что к нему почему-то тяготеют, скажем так, малограмотные программисты. Буквально слетаются, как мухи на, скажем так, сладкое.
Aqendo
Проблема goto в высокоуровневых языках не в самом goto, а в том, что к нему почему-то тяготеют, скажем так, малограмотные программисты. Буквально слетаются, как мухи на, скажем так, сладкое.
согласен полностью, мой первый яп который я начал изучать это луа и по незнанию НИЧЕГО в этой сфере я просто смотрел коды других людей и пытался найти закономерность(кстати луа как первый яп я считаю не годится) и у одного человека код был полностью из goto, ни одной функции, даже где это было бы удобнее, ну вот примерно на пол года изучения я и был запутан, почему у одного полностью goto, у другого функции, что из этого лучше использовать и т.д.
Aqendo
Весь код через goto жестко
там скрипт был на игру, не прям уж очень сложный, но полностью goto реально жестко
Snusmumriken
Весь код через goto жестко
Зачем нужны любые конструкции когда можно их все заменить на goto? :)
Snusmumriken
Затем, что есть функции
Зачем нужны функции когда есть goto?
Aqendo
аргументы к ним
Hello, World! 🎄
Зачем нужны функции когда есть goto?
Локальные переменные например
Hello, World! 🎄
И через goto ты не сделаешь, что-то типо ООП
Snusmumriken
Локальные переменные например
Зачем нужны локальные переменные когда ты не ограничен в количестве глобальных, а у тебя есть goto? Если добавить возможность перемещения к конструированной метке типа somevar = something .. "123" goto somevar А ля ссылки, сделаю и ооп.
Snusmumriken
Защита не нужна ) Просто не нужна и всё.
Aqendo
load("a=2")() print(a)
Snusmumriken
тогда страдает защита
Ребятки, попрогайте немножко на паскале, где нет локальных переменных, а сами переменные надо объявлять в начале. Мозги прочищает на отлично. И провоцирует на тотальное упрощение, чтобы делать как можно меньше переменных.
Snusmumriken
Потому что нужно несколько экземпляров класса, у тебя всё в глобально будет?
У меня будет глобальное хранилище экземпляров этого класса, разумеется. Буду в него пихать большинство экземпляров по необходимости.
Aqendo
с чего бы это
я занимался шифровками луа скриптов и это та ещё дрянь
Snusmumriken
Как это соотносится с goto? Таблички это тип данных, мне ничто не запрещает ими пользоваться. Делать их глобальными? Да. Перемещаться по инструкциям через goto? Тоже да.
Snusmumriken
Зачем функции, зачем циклы, зачем вложенные условия когда есть goto? :)
Aqendo
зачем луа когда есть goto
Snusmumriken
Goto: Бесплатно заменит вам любые конструкции любого яп. Покупай сейчас и получи полный комплект глобальных переменных в подарок.
Hello, World! 🎄
Как это соотносится с goto? Таблички это тип данных, мне ничто не запрещает ими пользоваться. Делать их глобальными? Да. Перемещаться по инструкциям через goto? Тоже да.
Я имел в виду func + table: function Cat(name_, age_) local data = {} data.name = name_ data.age = age_ function data.get_name() print("Cat name: "..data.name) end return data end mycat = Cat("Snusmumriken", 5) mycat.get_name() -- output: Cat name: Snusmumriken
Hello, World! 🎄
Зачем функции, зачем циклы, зачем вложенные условия когда есть goto? :)
Ну в ассемблере этого всего нету, но есть goto - jmp
Snusmumriken
А я бы организовал иначе. -- метод класса и аргументы self_foo = nil self_foo_arg1 = nil self_foo_arg2 = nil self_return = nil ::myclass_foo:: self_foo.x = self_foo.x + self_foo_arg1 self_foo.y = self_foo.y + self_foo_arg2 goto self_return -- вот что надо добавить для ооп obj_foo = {x = 10, y = 20} -- вызов метода self_foo = obj_foo self_foo_arg1 = 12 self_foo_arg2 = 32 self_return = "backmark" goto myclass_foo ::backmark:: print(obj_foo.x, obj_foo.y) > 22, 52 Работать на чистой 5.2 это не будет, надо влепить маленький мод на расширение goto.
Snusmumriken
Так ты не ответил на вопрос: зачем нужны функции и любые другие конструкции когда можно обойтись без них? Вопрос симметричен "зачем нужно goto если можно обойтись без него", если ты вдруг не заметил этой симметрии.
Lucky
game.timer = function(s) local function halt() -- halt logic end -- if animation_counter < 24 then if animation_counter < repeat_local then animation_counter = animation_counter + 1; play_animation(); halt(); return; elseif #main_stack > 0 then repeat_local = animation_repeats; step_local = animation_step; while forwerts() do -- nothing to do end halt() else walkout(); camps_calc(); end; end;
Lucky
Эрзац goto в Lua 5.1
Lucky
halt() - замена метки ::halt::
Lucky
forwerts() - замена метки ::forwerts::
Александр
а ещё вместо goto можно по идее сопрограммы использовать
Johann
О, кстати Никто не посоветует действительно хорошее и доходчивое статьё про coroutines? В мануалы плиз не отправлять, я уже там
Snusmumriken
О, кстати Никто не посоветует действительно хорошее и доходчивое статьё про coroutines? В мануалы плиз не отправлять, я уже там
Ну кароч, корутина это функция, из которую наружу можно сделать goto и обратно на то же место с теми же локальными переменными и прочим стеком. Суть: возможность параллелить разные задачки. Что нужно: таск-манагер который дёргает все активные корутины по очереди.
Snusmumriken
В качестве примера например вот, простой асинхронный хттп-сервер: https://pastebin.com/sJQCK5PJ Тут есть метод client:update, который заворачивается в корутину, и выглядит прямым и чётким. Но на всех моментах где может быть что-то длительное, происходят yield'ы наружу из этого метода, чтобы манагер клиентов мог перейти к следующему клиенту и обработать его. Зачем всё это нужно: чтобы прямо и чётко писать асинхронный код обработки клиентов, не городя всратые конечные автоматы.
Snusmumriken
Хы, а ещё на них можно делать асинхронные диалоги, чтобы калякать прямые сценарии, параллельно с обновлением геймстейта, анимациями, отрисовкой и всякой такой фигнёй. https://habr.com/ru/post/427135/
Snusmumriken
Уже давно сделал и кекаю
Snusmumriken
рай для ушей
Я синтезировал маленький квадратный звучок чтобы было максимально аутентично. Его ещё при сохранении пришлось укорачивать до 0.1 сек, иначе давал неприятную отдачу, не ту что обычно была на консольках.
Hello, World! 🎄
рай для ушей
В играх для gba, nes такие звуки встречаются
Hello, World! 🎄
Только немного другие, не как тут
Snusmumriken
Да не, это вполне аналог famicom nes синтезатора, тот делал практически то же самое, просто самая низкая квадратная нота.
Snusmumriken
Строка 137 по ссылке, очепятка
Статья не моя и мне пофигу, если очепятка — поправь. Автор кстати почему-то свалил из чата, надо будет его дёрнуть.
WDMR
и NES
Денис
Ребят, всем добрейший денечек! Вопрос: есть кастомная метатаблица. Она содержит заполненные поля и переопределенное метаполе index, которое всегда возвращает что-то (в данном случае возвращает строку с оповещением, что неизвестное поле). В один момент мне надо, чтобы эта таблица вела себя как стандартная, т.е., если поле не существует, возвращала nil. Могу ли я просто сделать вот так: self.states = setmetatable(self.states, {}) или мне нужно сделать что-то вроде: self.states = setmetatable(self.states, getmetatable({})) ?
Snusmumriken
Если ты хочешь сделать типа продолжение, чтобы если поле не нашлось и в поле __index метатаблицы, повесь на таблицу которая с __index'ом следующую метатаблицу с __index'ом.
Snusmumriken
t1 = {foo = 10} t2 = {foo = 20, bar = 30} mt1 = {__index = t1} -- мета-фигня отвечает ТОЛЬКО за поведение mt2 = {__index = t2} -- прицепленных к ней таблиц setmetatable(t1, mt2) -- связываем t1, чтобы недостающее искало в t2 o = setmetatable({}, mt1) -- вешаем поведение чтобы искало в t1 в случае чего o.foo --> 10, взято из t1 o.bar --> 30, взято из t2 по цепочке, ибо на t1 есть метатаблица поиска в t2 o.foobar --> nil, не найдено ни в o, ни в t1 ни в t2
Snusmumriken
Твоя строка self.states = setmetatable(self.states, {}) Вешает на таблицу self.states пустую метатаблицу, и ты её теперь никак не достанешь чтобы заполнить в ней управляющие поля кроме getmetatable. Вот эта строка возьмёт метатаблицу у пустой таблицы (её там нет), и повесит её на таблицу self.states, что приведёт буквально ни к чему. В метатаблице что-то должно быть чтобы она имела влияние. self.states = setmetatable(self.states, getmetatable({})) А так — читай статью. https://habr.com/ru/post/346892/
Денис
Давай пример поширше. Метатаблица определяет поведение прицепленных к ней таблиц. Если у метатаблицы есть поле __index, те таблицы на которые навешена метатаблица будут искать поля через это поле.
Пример такой. Имеем метатаблицу: automationModeProperty.states = setmetatable({ [0] = "trim read", [1] = "read", [2] = "touch", [3] = "write", [4] = "latch" }, { __index = function(self, key) return "Unknown automation mode "..key end }) В этом же пространстве есть функция, которая обращается к таблице и, если там значение есть, устанавливает индекс по API. if self.states[state+direction] then state = state+direction end В данный момент таблица всегда не nil, так что этот код не имеет значения.
Snusmumriken
Ну ды, всё так )
Денис
Ну ды, всё так )
А если сбить эту метатаблицу и определить поведение этой самой метатаблицы как обычной таблицы, то этот код сработает.
Snusmumriken
Задай пустую метатаблицу. Или убери setmetatable.
Денис
Задай пустую метатаблицу. Или убери setmetatable.
т.е., self.states = setmetatable(self.states, {}) ?
Snusmumriken
Маленькое уточнение.
Snusmumriken
Установи на свою табличку с ключами пустую метатаблицу, да. Или просто nil, должно сработать.
Денис
Спасыбе!
Денис
В общем, оно сейчас выглядит так: local mt = getmetatable(self.states) self.states = setmetatable(self.states, nil) if self.states[state+direction] then state = state+direction end self.states = setmetatable(self,states, mt) VS code молчит на nil, щас проверю на интерпретации
Денис
Ага, все значения стали nil
Денис
Ну ок, сейчас скормим ей в индекс саму себя
Денис
в общем, работает так: self.states = setmetatable(self.states, {}) if self.states[state+direction] then state = state+direction end
Snusmumriken
Если таблице скормить в __index себя, то она уйдёт в рекурсию и пошлёт тебя на переполнении стека если нет ключа )
Aydar
По "белке" даже отдельного чата нет... По описанию понравилось разделение массивов и таблиц и более предсказуемый GC (хотя один фиг не знаю как луашный сборщик работает). Сегодня попробовал встроить, преимуществ относительно Lua пока не почувствовал. Отчасти выбрал из-за того что кодовая база оригинального проекта плюсовая. Может попробую что-нибудь ещё...
Aydar
Белке?
http://www.squirrel-lang.org/
Luсky
Сквиррел
Igor
Аааа, дошло