Malandrinus 624 Опубликовано 6 Февраля 2015 (изменено) писать в глобал или еще куда - какая в принципе разница, блин? Особенность Lua в том, что переменная ищется начиная от текущего уровня вложенности и вплоть до глобального, поэтому к глобальным переменным на самом деле обращение идёт медленнее. Но, на мой взгляд, это не самое важное. Важнее то, что глобальная область одна, и сваливать туда все переменные - чревато конфликтами по именам. Действительно лучше ограничивать область видимости, ну и как следствие время жизни, переменных. Народ, как-то реально стало заметно некое напряжение в этой теме. Некоторые комрады, не будем тыкать пальцами, определённо перегибают палку и практически переходят на личности. Это недопустимо. Прошу всех критически отнестись к своему стилю общения и при необходимости пересмотреть. Изменено 6 Февраля 2015 пользователем malandrinus 1 1 Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Поделиться этим сообщением Ссылка на сообщение
Malandrinus 624 Опубликовано 6 Февраля 2015 (изменено) self.sm:call("on_drop", obj) - self. в примере как бы явно указывает на то, что относится к актору, а не к внешней системе, нет ? Нет, это я просто не до конца цитирую код. self.sm - это ссылка на глобальный менеджер событий, которую я сохранил ранее для экономии. self.sm = ogse_signals.get_mgr() для того, чтобы каждый раз не писать полный вызов, который выглядел бы так: ogse_signals.get_mgr():call("on_drop", obj) Изменено 6 Февраля 2015 пользователем malandrinus Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Поделиться этим сообщением Ссылка на сообщение
Malandrinus 624 Опубликовано 6 Февраля 2015 (изменено) @Andrey07071977, Общее правило: чем локальнее данные, тем лучше. Чаще всего это лучше с точки зрения ограничения видимости, дабы уменьшить вероятность конфликтов. В случае Lua ещё и быстрее работает.PS: на самом деле в данном случае нет особой разницы, просто я уже рефлекторно следую этим правилам. Изменено 6 Февраля 2015 пользователем malandrinus Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Поделиться этим сообщением Ссылка на сообщение
Malandrinus 624 Опубликовано 6 Февраля 2015 У меня так вообще класс-обертка, который инкапсулирует все взаимодействие с подобным менеджером. Поскольку я повёрнут на ООП, то я исходно сделал менеджер сигналов как класс, а не модуль. Таким образом, можно завести несколько объектов такого класса =) Помнится, была идея использовать отдельный экземпляр менеджера событий для системы управления лампочками. Дело в том, что там я активно использовал очерёдность выполнения АКА низкоприоритетные апдейты (их тут называли поллингом, но по-моему не совсем подходит под определение). Смысл использования отдельного менеджера событий был в том, чтобы изолировать очереди из десятков лампочек от остальных очерёдных событий. Но потом отказался от этой мысли и все лампочки навесил на глобальный менеджер. Задержка срабатывания получилась практически незаметная. Очерёдные или низкоприоритетные события, это когда все подписчики на событие срабатывают не все сразу, а по одному на вызов. Очевидно, что это имеет смысл только для периодических событий, типа апдейтов и делается в основном для распределения нагрузки, хотя при желании можно придумать и другое применение. Ну знаете в общем эту оптимизацию, когда заводим в апдейте биндера актора циклический счётчик и вызываем по этому счётчику вызовы по одному за апдейт. При использовании системы событий это можно сделать автоматически так: function attach(sm) sm:subscribe({signal = "on_update", fun = this.on_update_low_priority, queued = true}) end function on_update_low_priority() end Понятно, что в этом случае периодичность срабатывания on_update_low_priority будет во столько раз меньше апдейтов актора, сколько подписчиков будет на низкоприоритетный апдейт. Поскольку их число заранее неизвестно, то понятно также, что период может быть весьма неопределённым. Если таких подписчиков много, то период может быть весомые доли секунды или даже секунды. Но секунды - это уже совсем экстрим на очень слабых машинах. Зато имеем распределение нагрузки между апдейтами. Все сохраняемые таймеры у меня по-умолчанию ставятся на низкоприоритетный апдейт. Лампочки по расписанию также срабатывают по этому принципу. Не так уж важно, что они загорятся на секунду позже, а вот если все сразу, то может быть приличный лаг. Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Поделиться этим сообщением Ссылка на сообщение
Malandrinus 624 Опубликовано 6 Февраля 2015 не могу не дать эту ссылку На мой взгляд, автор данной статьи попросту оправдывает свою лень, призывая в помощь Силу Самодокументированного Кода. Как там Аня сказала? "он не мифический, но недостижимый". Признаться, не хочется спорить с этим перцем. Я просто предлагаю поглубже познакомиться с исходниками x-ray. Там неплохой код в смысле самодокументации. Адекватные названия переменных и функций, отформатировано... Желаю удачи с разбором. Понадобится. не нашел применения для низкоприоритетных ну как же? По большому счёту, низкоприоритетные - это почти все периодические. Исключением являются те, что подразумевают некую визуально заметную реакцию, и ещё некоторые. Т.е. если к примеру мне надо сделать что-то с предметом по факту его создания в инвентаре, но при этом надо дождаться появления его клиентской части по таймеру с условием на выход объекта в онлайн, то здесь ждать полсекунды наверное нехорошо. Почти во всех остальных случаях можно не заморачиваться на точность срабатывания в четверть-пол секунды. На самом деле надо задавать прямо противоположный вопрос, вот этот конкретный обработчик апдейта должен ли быть высокоприоритетным?С заданным периодом проверки - тоже неплохая опция. Более того, можно было бы предложить развитие этой идеи скажем в плане рандомизации времени срабатывания. Вот выбросы или что-то ещё в игре можно было бы повесить на такие события. Наверное было бы неплохо как-то объединить разработки. Я давно не трогал свою реализацию, а там очевидно можно что-то изменить и наверное немало. Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Поделиться этим сообщением Ссылка на сообщение
Malandrinus 624 Опубликовано 7 Февраля 2015 Как эффективнее, так и лучше А критерий эффективности какой? Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Поделиться этим сообщением Ссылка на сообщение
Malandrinus 624 Опубликовано 23 Августа 2015 is_ammo() А это в движок надо зашивать? Можно спросить зачем? На этот вопрос я могу ответить. Во-первых, потому, что это родная движковая функция, которую надо только вытащить в скрипт. Во-вторых, даже если бы такой родной движковой функции не было, то её бы стоило сделать, поскольку информация о классе объекта - это информация сугубо внутренняя движковая. Скрипту, вместо специализированного объекта, выдаётся универсальная скриптовая оболочка. Посему, выяснение типа скриптовыми методами - это неизбежно костыли, громоздкие и медленные, а возможно и глючные. Короче, такая функция - самый типичный кандидат на движковую реализацию. Другое дело, что по хорошему надо было бы переделать всю скриптовую модель так, чтобы такие функции были бы не нужны в принципе. Но это тема для другого разговора. Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Поделиться этим сообщением Ссылка на сообщение
Malandrinus 624 Опубликовано 25 Августа 2015 (изменено) obj:method(...) и obj.method(obj, ...) Разницы нет. Одно является "синтаксическим сахаром" другого, т.е. это эквивалентные конструкции. Изменено 25 Августа 2015 пользователем Malandrinus Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Поделиться этим сообщением Ссылка на сообщение
Malandrinus 624 Опубликовано 15 Октября 2015 лучше юзать #define, чем typedef, чтобы "наверняка"Это чушь. #define - это элемент препроцессора, простая макроподстановка одного текста вместо другого, что может использоваться и для других целей кроме "заворачивания" длинных типов.typedef же является не конструкцией препроцессора, а частью синтаксиса языка. Особенность языка в том, что новый тип и здесь не создаётся, а только создаётся синоним, но тем не менее полученный синоним является с синтаксической точки зрения корректным типом. Нашёл пример в сети для иллюстрации разницы: typedef int* int_p1; int_p1 a, b, c; // a, b и c все являются указателями #define int_p2 int* int_p2 a, b, c; // только первая переменная будет указателем Короче, для указанных целей создания короткого синонима длинного типа typedef безоговорочно предпочтительней #define. Если есть желание развиваться, то рекомендую почитать насчёт препроцессора языка С/С++. Что это такое, какое место занимает в процессе компиляции, какие проблемы может вызывать при использовании, как их избегать. 1 Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Поделиться этим сообщением Ссылка на сообщение
Malandrinus 624 Опубликовано 3 Декабря 2015 @НаноБот, все эти идеи идут от совершенно неверного понимания сути ассемблера. Ассемблер лучше вообще не воспринимать как язык, а думать о нём как о буквальном интерфейсе к процессору. Когда я пишу mov eax, ebx, я буквально говорю разместить в памяти совершенно определённую инструкцию процессора, которая составлена из некой фиксированной части, говорящей, что это MOV и части, отвечающей за аргументы, в данном случае eax и ebx. Когда же ты начинаешь писать вещи типа eax = eax + ebx, то ты сразу уходишь от вот такого непосредственного указания. Конкретно eax = eax + ebx конечно можно транслировать в одну инструкцию, а вот уже eax = ebx + ecx - уже нельзя, и теряется весь смысл затеи. А потом я захочу написать eax = ebx + ecx + edx и начну возмущаться, что это в таком "высокоуровневом ассемблере" почему-то невозможно. Тогда уже возьми компилятор любого языка высокого уровня и не парься с ассемблером. Вообще говоря, ассемблер сейчас мало актуален для разработки обычных программ. Тривиальные вычисления компиляторы оптимизируют лучше, чем это сделает на ассемблере вручную средний программист, поэтому ассемблер нужен в основном для сугубо системных вещей, доступа к каким-то аппаратным ресурсам и т.п. Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Поделиться этим сообщением Ссылка на сообщение
Malandrinus 624 Опубликовано 3 Декабря 2015 @НаноБот, суть в том что инструкции называются максимально просто и имеют формат близкий к высокоуровневом ЯП. Да понял я тебя, и могу только повторить уже сказанное. Формат, близкий к языкам высокого уровня, но при этом со всеми ограничениями ассеблера - это ненужный уродец. Если я могу записать конструкцию eax = eax + ebx, но не могу записать что-то вроде eax = ebx + ecx, то ничего мне это не даёт, кроме как запутает. Пойми же, ассемблер - не язык высокого уровня. Его мнемоники тесно связаны с тем, как это всё устроено в памяти. Формат <мнемоника> <операнд1>, <операнд2> - это максимально соответствует бинарному формату в памяти. Кроме того, все остальные мнемоники, а их куда как больше, нежели мнемоник копирования и простых арифметических операций, имеют такую же вышеописанную структуру. Представь себе бедлам, который внесёт разнобой синтаксиса. А вот например есть мнемоника не просто копирования из регистра в регистр, а копирование из регистра меньшей разрядности в регистр большей. При этом надо решить, как заполнять старшие разряды: нулями или знаковыми битами. Для этого есть две разные инструкции копирования, а как ты предлагаешь это оформить в виде высокоуровнего кода? И есть ещё море подобных возражений. Кстати, более подробное изучения SSE показывает мощную оптимизацию по сравнению С++ кодом, т.е. низкоуровневый Fvector4 (xmm) компилятор студии почему-то не понимает. Прекрасно понимает. Я видел кучу кода, где все эти матричные операции компилировались с использованием SSE. Вообще-то для матричной/векторной алгебры вообще надо пользоваться не самопальными, а специальными библиотеками, где векторизация задействована в полной мере и оптимизирована заранее, возможно и с использованием ассемблера. Есть маза переписать на ассемблер =) Я думаю, что тебе стоит попытаться для начала написать на ассемблере какую-нибудь простую программу. В общем, мне не нравится программировать на С++ ...компилировать проекты по 40 минут только одна xrGame.dll, ...это около 17-19 ГБ живого веса. ...Это я про конкуренцию ассемблера и С++ в рамках проекта модинга движка. Извини, но если подытожить сказанное, то ты просто не представляешь о чём говоришь. Одна строка C++ или другого языка высокого уровня - это в среднем десятки инструкция ассемблера. Добавь к этому на порядки большую сложность программирования на ассемблере, т.е. на написание и отладку аналогичного фрагмента на ассемблере уходит в десятки раз больше времени, чем на любом языке. 17-19 мегабайт кода С++ тогда превратятся в порядка 200-300 Мб, а время разработки сталкира в шесть лет превратится во все 60. Я не шучу. 1 2 Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Поделиться этим сообщением Ссылка на сообщение
Malandrinus 624 Опубликовано 5 Декабря 2015 МАСМ понимает много чего из языков высокого уровня, и на нем реально можно делать много чего. ... То есть, можно делать то же что на С++ Объясни пожалуйста, а что мешает тогда просто взять СИ и его использовать? Я не говорю про С++ с его классами, шаблонами и т.п., а только про старый добрый процедурно-ориентированный СИ. Вот застрели, а я не вижу ни малейшего преимущества в ассемблере перед обычным СИ. Тем более, что ты хочешь использовать там макросы, превращающие его в некое подобие нормального языка. Но все ограничения то останутся: с гулькин нос регистров, ограничения по набору операций, никаких типов и соответственно контроля, даже с этими макросами элементарные действия требуют жуткого геморроя по сравнению хоть с каким угодно языком и т.д. Я более скажу. Твои слова насчёт того, что дескать проще распространять и собирать - это ты на самом деле принимаешь за эффективность элементарную неразвитость средств разработки для ассемблера по сравнению со средами для языков высокого уровня. Формально говоря, этапы сборки программы для ассемблера ровно такие же, как и для СИ: компиляция, линковка. Если ты такой эстет, то ничто не мешает и на СИ разрабатывать в блокноте и пользоваться сборкой из командной строки. Будет тебе точно такая же "эффективность и простота". А метод ХЕ или ассемблерных вставок-правок так и останется универсальным для ориг. версий. О боги геймостроя! Да если бы у меня пять лет назад были исходники, я бы и думать не стал ни про какой ассемблер. А сейчас проект ХЕ для меня лично актуален только постольку постольку к нему привязан ОГСЕ. Обратная совместимость - страшная штука. Так бы забыл уже как страшный сон. 4 Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Поделиться этим сообщением Ссылка на сообщение
Malandrinus 624 Опубликовано 10 Декабря 2015 (изменено) Предлагаю для обсуждения простую мысль. Часто можно встретить функцию, написанную примерно в таком стиле: function fff() if cond1 then if cond2 then if cond2 then if cond3 then if cond4 then --do_something end end end end end end С алгоритмической точки зрения здесь всё нормально, однако подобное крайне плохо воспринимается. Что там надо сделать после проверки тысячи условий уползает куда-то вправо и теряется где-то в середине функции (и в середине монитора) на фоне лестницы кода.В своей практике я взял за правило всегда заменять этот код, насколько это возможно, на эквивалентный ему в таком стиле: function fff() if not cond1 then return end if not cond2 then return end if not cond3 then return end if not cond4 then return end --do_something end Это не только компактнее, но и читается гораздо лучше, поскольку весь код на одном уровне, а собственно осмысленное действие, которое выполняется после всех проверок, выделено в коде более определённо. Это конечно отступление от Истинно Структурного Программирования, но на это как-то и начхать. Есть ли какие-то мысли по этому поводу? ЗЫ: Вполне возможно, что когда-то я это уже говорил в этой или подобной теме. Уже не вспомнить. Однако, судя по тому, что народ сам так почти никогда не делает, не грех и повторить вброс. Изменено 10 Декабря 2015 пользователем Malandrinus 1 1 1 Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Поделиться этим сообщением Ссылка на сообщение
Malandrinus 624 Опубликовано 11 Декабря 2015 (изменено) куда делся оператор and? Ну я не стал расписывать более тяжёлый вариант, из-за которого собственно и делают каждое условие по-отдельности. function fff() if cond1 then ... -- долго вычисляем cond2 local cond2 = ... if cond2 then ... -- долго вычисляем cond3 local cond3 = ... if cond3 then ... -- и т.д. if cond4 then if cond5 then --do_something end end end end end end мы говорим о субъективной вещи. Кому то лесенка вполне читаема. Разница между вложенными и последовательными if вполне осязаемая. Когда читаешь вложенные if, то для расшифровки всей конструкции надо "отложить в памяти" каждый if в этой конструкции. Это наподобие рекурсивного вызова: каждый вложенный if - очередной уровень рекурсии. При линейном же расположении условий такого нет: закончилось условие - забыл про него, перешёл к следующему. Когда подошёл к самому внутреннему уровню, то ничто уже не засоряет в сознании то действие, которое собственно выполняется. Отвечаю сразу тем, кто скажет что-то вроде: "что, сложно немного лишнего напрячься и подумать?" Да, сложно. Мне хватает реальных сложностей, чтобы не создавать себе сложности искусственные. А это именно сложность. Одно такое место в коде, другое - и вот уже я трачу на его разбор не десять минут, а час. Собственно, из-за концепции структурного программирования и делают, как ты говоришь "лесенкой". Ну так я же и сказал, что множественные return нарушают. Это примерно тоже самое, что выходы с помощью goto из вложенных циклов или тех же if-ов. Кстати, очень жаль, что в версии Lua для сталкира нет goto. В поздних то версиях уже добавили. Но в обычных условиях, таких простынь вряд ли получится Ты шутишь что ли?! Да меня уже от этих "лестниц" тошнит, столько я на них насмотрелся. Вот все ругают оператор goto. Не пойму чем он так плох? Плох тем, что с его помощью без должного понимания основ структурного программирования и самодисциплины можно сделать совершенно нечитаемый и крайне нестабильный код. Хорош же тем, что при наличии указанных понимания и самодисциплины можно сильно упростить код в ряде случаев. Типичный пример - прервать вложенные циклы. Нет совершенно никакого вреда в том, чтобы сделать выход из самого внутреннего цикла по условию на метку снаружи всех циклов. А без goto для этого придётся извращаться. Типичный же негативный пример, когда начинают с помощью if и goto имитировать циклы, или делают циклы с пересекающимися телами. Ну там простор для извращений вообще безграничный. А вот помню в первых версиях BASICа можно было и метки вычислять. Можно было делать невероятно лаконичные, но абсолютно нечитаемые программы. В те времена для этого были свои причины, поскольку на восьмибитных машинах память считали килобайтами. Изменено 11 Декабря 2015 пользователем Malandrinus 1 Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Поделиться этим сообщением Ссылка на сообщение
Malandrinus 624 Опубликовано 13 Декабря 2015 Ну этот код можно точно также написать в одно условие Вычислить все части условия заранее? Не покатит, поскольку такая матрёшка из условий почти всегда подразумевает, что какие-то из условий невозможно вычислить, если не выполняются какое-то из предыдущих. Типичный пример - ищем по id серверный объект, потом клиентский, потом проверяем тип, потом ещё что-то, что применимо только к этому типу, и т.д. а если так? Мне кажется, что так ещё более мудрёно. И опять же применимо то, что я выше написал. Часто, если не всегда, вычисление очередного условия в "матрёшке" подразумевает выполнение предыдущего условия (и также использует данные, полученные на этапе вычисления предыдущих условий). В твоём же варианте все условия изолированы. Скорость Lua достаточно высока чтобы не обращать внимания на создание в стеке таких локальных переменных. =) Я не имел в виду скорость трансляции при выполнении. Я говорил о скорости разбора кода человеком. Человек - очень медленное устройство, поэтому всё развитие технологий разработки ПО связано с повышением эффективности именно человека, как слабого звена в цепочке. Обратите внимание, что весь прогресс в программировании непременно связан с фактическим снижением скорости работы программ. Зато программисту работать всё легче и легче. Если скриптер образованный, то ему по силам прочитать любой вариант кода. Тебе нравится тратить время зря? Когда-то и я по молодости считал, что трюкачество в коде - это круто, но это было давно. Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Поделиться этим сообщением Ссылка на сообщение
Malandrinus 624 Опубликовано 14 Декабря 2015 @RayTwitty, Смущает? Да за такой код по рукам бить надо. У тебя в цикле перебора всего диапазона id три раза вызываются функции, которые сами по себе перебирают все объекты (вообще все или на уровне). Причём третий вызов и вовсе не нужен, и стоит только затем, чтобы что-то доказать. Впрочем, речь то не об этом. Ты опять себе упростил задачу. Я же ранее явно в примере кода указывал "долго вычисляется условие такое то". Ключевое слово "долго", т.е. в несколько строчек. И не упакуешь ты тогда всё условие в одно выражение. Но я ведь могу в эти функции передать Да можно конечно. Вот только ответь на простой вопрос: решает ли это ту задачу, с которой я начал - сделать код проще и понятнее? Просто погляди критичным взглядом и сравни три варианта: исходную матрёшку, твой вариант, вариант линейной записи. Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Поделиться этим сообщением Ссылка на сообщение
Malandrinus 624 Опубликовано 14 Декабря 2015 Кстати в JavaScript присваивание переменных возвращает собственно присвоенное значение. Украдено из СИ, как и общий синтаксис. Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Поделиться этим сообщением Ссылка на сообщение
Malandrinus 624 Опубликовано 14 Декабря 2015 Обычно, я "долгие вычисления" делаю где-то в другом месте, а не внутри общей функции Вроде уже несколько раз объяснял. Совершенно типичная ситуация, что ты не можешь вычислить условие 2 до тех пор, пока не выполнено условие 1, а условие 3 до тех пор, пока не выполнено условие 2 и т.д. Неужели это настолько непонятно? Ты не можешь сделать это заранее. И не будешь же ты выносить в функцию несколько строчек специально для того, чтобы где-то в одном месте соединить несколько условий в одну строку. Функции не для этого создают, да и лишено это смысла, поскольку не добавит коду ни понятности ни эффективности. Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Поделиться этим сообщением Ссылка на сообщение
Malandrinus 624 Опубликовано 15 Декабря 2015 По законам мат. логики оно итак не будет выполняться: a & b & c Не стоит поминать всуе вещи, о которых имеешь, скорее всего, смутное представление. Погляди для начала здесь, что вообще такое математическая логика. https://ru.wikipedia.org/wiki/Математическая_логика Я бы и сам не рискнул произносить это название, поскольку не математик ни разу. Вообще говоря, то, что мы в бытовом смысле понимаем под логикой, в мат.логике являетя весьма маленьким разделом под названием "Логика высказываний" https://ru.wikipedia.org/wiki/Логика_высказываний В этом аппарате нет никаких указаний насчёт обязательности/необходимости вычисления входящих в выражение условий. Они там просто есть, как уже готовые факты. Подобное имеет смысл как раз в программировании, а точнее в императивных языках программирования, где вообще имеет смысл, что что-то там вычисляется и в каком-то там порядке. Да и там эта фишка не всегда обязательная, иногда даже решаемая на уровне опции компилятора. Иногда обязательная, иногда просто возможность доп. оптимизации. Разумеется, если можно безболезненно, без потери читаемости и эффективности кода, соединить несколько условий в одно, то в этом действительно часто есть смысл. Хотя и тогда я иногда всё равно разбиваю условия на группы уже по смысловым соображениям или по соображениям отладки. Но я то говорил об общем случае. Если выражении выше условие "b" вычисляется, во-первых, при условии истинности условия "a", а, во-вторых, на основе данных, которые вообще появляются только после (и вследствие) вычисления условия "a", то тогда в попытке соединить всё в одну строку имеем проблемы. Для начала, если условие вычисляется в несколько строк. Единственным выходом является только заключить всё вычисление выражения в функцию, что не есть хорошо. Функция может получиться сугубо одноразовая (что само по себе лишает её смысла), а кроме того нужно туда ещё передать данные от вычисления предыдущего условия. И далее, здесь мы нарываемся на побочные эффекты языка, поскольку большинство языков не гарантируют последовательность вычисления компонент выражения. Вот уже эти два соображения, многострочное вычисление выражения и зависимость условий, уже вынуждают отказываться от объединения выражений в одну строку. А тут кстати упоминали ещё и вариант с веткой else. Вот тот-же самый код матрёшкой, но уже с альтернативными ветками. function fff() if cond1 then ... -- долго вычисляем cond2 local cond2 = ... if cond2 then ... -- долго вычисляем cond3 local cond3 = ... if cond3 then --do_something else -- сделать что-то, если не сработало условие 3 end else -- сделать что-то, если не сработало условие 2 end else -- сделать что-то, если не сработало условие 1 end end И опять линейный вариант смотрится куда как более читаемо. function fff() if not cond1 then -- сделать что-то, если не сработало условие 1 return end ... -- долго вычисляем cond2 local cond2 = ... if not cond2 then -- сделать что-то, если не сработало условие 2 return end ... -- долго вычисляем cond3 local cond3 = ... if not cond3 then -- сделать что-то, если не сработало условие 3 end --do_something end А здесь можно ещё упомянуть, что очень часто эти условия на самом деле являются затычками. Особенно тяжело с этим в практике модостроения в силу понятной низкой дисциплины большинства скриптёров. Т.е. очень часто вот такая конструкция в функции: if not cond1 then return end имеет буквальный смысл "не делать ничего, если функция вызвана неправильно". cond1 - это в данном случае некая проверка валидности аргументов, ну к примеру проверка существования клиентского объекта. Абсолютно чудовищный подход, который привёл к трате большей части человеко-часов в модостроении. На самом деле вместо такого выражения должен стоять ассерт - программный вылет по условию - который позволит выловить невалидный вызов функции и, в месте её вызова, исключить ситуацию, когда в неё что-то не то передаётся. "Линейный дизайн" кода в целом хорошо сочетается с этой идеей, поскольку ассерты - они как-то не располагают к вложенности кода. Проверил - здесь же вылетел. Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Поделиться этим сообщением Ссылка на сообщение
Malandrinus 624 Опубликовано 15 Декабря 2015 я буду поминать те вещи, которые считаю нужным твои линки тут неуместны. =) Да кто же тебя остановит? Просто несколько забавно видеть упоминание мат.логики для красного словца. В тех языках, которые я подразумевал (и которые скорее всего подразумевали другие), это свойство прекрасно работает. Императивные ЯП не в полной мере реализуют аппарат логики. Наиболее близки к истинному логическому аппарату функциональные ЯП, но это вообще совершенно другая песня. Ты полностью проигнорировал сказанное про побочные эффекты. Это как раз фишка именно императивных ЯП и как раз то, что нарушает строгое соответствие логике: зависимость одних условий от других как в плане вычислимости вообще, так и в плане использования данных от предыдущих вычислений. Смысла не лишает, если хочется визуально отделить одно от другого. Да и возможно, в дальнейшем ещё понадобится использовать эту функцию где-нибудь. Завести функцию "про запас", только чтобы выделить несколько строк? Ну ок. Хотя при чём здесь тогда читаемость алгоритма? лесенку удобно рассматривать на 21:9 Береги глаза смолоду, пригодятся позже. Кроме того, я уже пытался ранее объяснить, в чём проблема с матрёшкой. Здесь не в геометрии дело. На её разбор требуется больше усилий, больше краткосрочной памяти, больше времени в итоге. Это неважно, умный человек или нет. На более сложную задачу в любом случае потребуется больше времени. Не жалко времени? Вот кстати про монитор. Не сильно то помогает ширина монитора. Скорее помогает высота, а сейчас практически вымерли мониторы 3х4 с оптимальной для программирования высотой. В итоге широкий монитор 24" примерно настолько же удобен для программирования, как старый 19". Плагины Total Commander для работы с игровыми архивами: Архиваторный плагин (для работы с одиночным архивом): link1 link2 Системный плагин (для распаковки установленной игры): link1 link2 Поделиться этим сообщением Ссылка на сообщение