В ежедневной практике программирования на платформе 1С оператор Goto (Перейти) практически не встречается. Не удивительно, что половина специалистов даже не подозревает о существовании данного оператора. Ну, а знающим он внушает ужас, и его стараются избегать. Так что же это за редкий оператор, и для чего он нужен?
(2) у вас правильная декомпозиция. Но я сделал упрощенный пример - на практике с этим деревом может быть связано еще несколько расчетов да и происхождение может быть мутным (первоначально делали запрос для вывода отчета, а потом делаем второстепенные расчеты, которые не смогли выразить с помощью языка запросов). Тогда будем делать еще больше процедур, а потом героически пытаться в них не запутаться?
Т.е. у вашего решения есть плюс - не нужно вручную отслеживать наименование меток, можно использовать подсказки от EDT. Но есть и минусы - кода банально больше и возникает задача его упорядочить; появляются уровни абстракции усложняющие доработку, контекст модуля разбухает и потребляет чуть больше ресурсов.
P.S. Тогда и от Прервать/Продолжить можно отказаться - все отлично декомпозируется на систему вложенных процедур и функций.
В типовых конфигурациях 1С данный оператор не применяется, за очень редким исключением (для быстрого выхода из вложенных циклов).
Скорее всего, про это есть в стандартах методик разработки.
Также, в типовых конфигурациях стараются избегать конструкций Попытка - Исключение. Пользователю надо показывать ошибки, чтобы он реагировал и звал программиста. Плюс, "Попытка-Исключение" - это часто лень разработчика (ON ERROR RESUME NEXT). Будет вторая статья на эту тему?))
(5)В типовых избегают Попытка-Исключение? Не смешите мои подковы. Да в типовых этой конструкции хоть лопатой жри.
Лень программиста писать обработку исключений - не повод для игнорирования конструкции очень важной для избегания падения критического кода во время исполнения.
Кроме того, это единственный способ не обрушить программу при выполнении явных преобразований типов.
(8) Возьмите типовую (БП, КА, УТ и т.п.) и подсчитайте - сколько раз встречается отдельно слово "КонецПопытки;" во всех модулях, и сравните это с количеством, например "КонецЕсли;" или "КонецЦикла;".
Вот пример:
БП 3.0.130.22
"КонецПопытки;" = 9 935 раз;
"КонецЦикла;" = 147 801 раз; (почти в 15 раз больше)
"КонецЕсли;" = 632 876 раз; (почти в 64 раза больше)
Вот из этого я делаю вывод, что 1С старается избегать конструкций "Попытка-Исключение". То есть, по-возможности не использовать, но в крайних случаях - это допустимо.
, но методологически это неправильно. Т.к. такая обработка ошибок затрагивает и нештатную ситуацию, когда в Делитель не число, а, например, дата (или Ссылка, или Неопределено, или...).
Это примерно 2,5% кода. А если сравнивать количество строк, обернутых в Попытка-Исключение с общим количеством строк - процент будет меньше.
(34) Техподдержка, пользователь присылает скриншот ошибки, доступа в базу пользователя нет (в журнал не зайти). Связи с пользователем нет. Раньше по скрину ошибки можно было хотя-бы увидеть строку кода, найти и проанализировать его, сейчас - нет.
(35) Работу с транзакциями стараюсь всегда делать без Попытка-Исключение. При исключениях, как и при выходе из процедуры, если транзакция не была зафиксирована - происходит *. Обработку больших массивов данных - тоже стараюсь делать без попыток, и, например, при обмене данными 1С - если происходит ошибка, предпочтительнее завалить обмен, чем продолжать грузить инфу с непонятными искажениями. Если же выбирается "продолжить в случае ошибки", то как минимум, ошибки эти где-то нужно собирать и мониторить.
(43) Согласен с Вами. Судя по обилию комментариев и интересу к теме - надо бы написать статью))
--
Писать код, который будет избегать ошибок (с проверками на тип данных, на наличие поля у справочника и т.п.) - всегда сложнее, чем воткнуть "Попытка - Исключение", но использовать второй вариант - это, скорее, лень программиста. Вот я о чем толкую.
Однако, всё-же, есть фрагменты кода, где нет возможности избежать исключительных ситуаций (например, работа с внешними обработками, работа с интернет-функциям), но нужно их обработать и при ошибке выполнить альтернативный алгоритм.
(48) не нужно в попытку пихать деление и ловить ошибку деления на ноль
Сама по себе попытка это же не некое условие, а обработка нештатной ситуации во время которой платформа выполняет затратные по ресурсам операции, строит тот же стек вызова, формирует там у себя в мозгах текст ошибки и прочие прелести, что явно дольше отрабатывает нежели проверка на 0 в простом Если. Можно конечно тип переменной еще проверить и если не число тогда ошибку выкинуть самостоятельно мол типа чего вы пытаетесь число на строку поделить, но это уже тоже вызывает доп расходы на вычисления этих типов данных. Тут бы помогла статическая типизация но ее в 1С нет.
(10)Не корректная оценка. По вашей логике в попытку исключение нужно заворачивать каждую строчку кода, но у этого оператора определенная область применения. Сравните с количеством функций и процедур.
Можно так же смело заявить, что 1С умышленно не использует циклы с условием (Пока условие Цикл), и везде их заменяет на Циклы типа Для Каждого или Для Индекс = 0 По...
(5) Статья на тему Try-Catch ? А смысл? Все и так используют этот оператор настолько часто, что теперь трудно находить ошибки банальной галочкой "остановка по ошибке".
А вот если бы существовала альтернативная Попыткам методология написания стабильного кода, то это реально хорошая тема для статьи.
(13) да блин, вы не в теме.
Речь о том, что пока ты доберешься до своей РЕАЛЬНОЙ ошибки - тебе надо продраться через тонну остановок в местах где прогеру тупо лень было типы значений проверить.
И использовать «остановку по ошибке» уже не хочется. Потому что палец на ф5 уже устал.
Моё мнение - попытка должна быть только в проде в критичном коде в новых участках (чтобы точно не упало) при срочной доработке
(9) Ошибка это в Исключение проглатывать ошибку и ничего не делать.
Код
Попытка
// делаем что-то умное приводящее к ошибке
Исключение
// ничего не делаем
КонецПопытки;
Показать полностью
Я наоборот часто делаю эскалацию ошибки выше, чтобы вызывающий код страдал от своей тупости что передает невесть что приводящее к ошибкам.
Код
Попытка
// делаем что-то умное приводящее к ошибке
Исключение
// делаем что-то умное, что обязательно надо сделать при возникновении ошибки
ВызватьИсключение; // даем вызвавшему коду понять что он олень
КонецПопытки;
Ошибки можно писать в журнал регистрации. Пользователю можно выводить нужное сообщение без стэка с кодом 1с. В новых версиях платформы реализовали на уровне платформы уже
(10) Не сравнивайте жопу с пальцем. Вы бы еще сравнили с количеством "КонецПроцедуры" и "КонецФункции". Никто не говорит, что Попытку надо пихать во все щели.
Судя по вашей логике, разработчики так же против использования транзакций - всего 1368 раз встречается НачатьТранзакцию() в той же УТ (это у меня еще и с кучей расширений, а если брать "чистую", то еще меньше)
А использовать GoTo народ просто фактически не умеет - выросло уже не одно поколение прикладных программистов, которые фактически даже не знают что это такое и для чего нужно. Поэтому-то и обфускация множественными goto так дико бесит. А на самом деле это один из самых простых для распутывания способ.
(14) Согласен. Эта очень странная выборка данных. Не понятно что анализируем и что нам это дает. Давайте ещё сравним количество использования буквы а и б.
Раз уж речь зашла о странных платформеных решениях, давайте поговорим о том, что константы и перечисления хранятся в бд как отдельные таблицы каждая. Есть много вопросов и к последовательности разработки самой платформы. То есть они как-то додумались реализовать задачи, ботов и т п, а гуид в запросе это слишком сложно, нужно больше времени. Вопросы к самой концепции хранилища. Отходя чуть в сторону, проблемы общей методологии найма 1с-ников.
И это только то что первое в голову пришло.
(15) Рекомендую "Вспомнить" или "Прочитать" как хранились константы или периодические реквизиты справочников в 7.7 в табличке _1SCONST и вспомнить как "легко и просто" было переливать такие данные запросом из таблицы
(15)гуид в запросе это скорее не сложно, там по политическим соображениям кое что не делают, есть вещи которые нужно давать с опаской программистам без надлежащей квалификации.. вспомните как долго сопротивлялись делать запись в внешние источники, как долго сопротивлялись дать возможность пакетного запроса в дин списки.. Ну вот дин списками то оказались от части правы, я видел формы где напихано в дин список целые отчеты, а потом эти горе программисты удивляются почему это не работает или "нам что то вешает сервер".
Предложу ещё один пример разумного использования оператора Перейти в 1С:
Если мы дорабатываем типовую функцию в расширении с директивой &ИзменениеИКонтроль и нам по какой-то причине нужно пропустить большое количество строк типового кода и перескочить в середину процедуры.
&ИзменениеИКонтроль
Функция СложныйМногоступенчатыйАлгоритмНа100500Строк()
//100500 строк нужного кода
#Вставка
Перейти ~ПропуститьНенужныйКод;
#КонецВставки
//100500 строк НЕ нужного кода
#Вставка
~ПропуститьНенужныйКод:
#КонецВставки
//100500 строк нужного кода
КонецФункции
менее наглядно для последующей поддержки, т.к. сложно будет найти поиском/глазами конец фрагмента пропускаемого кода
>Да просто закомментировать
ломает последующее обновление
>#Удаление
>#КонецУдаления
подойдёт для этого упрощённого примера (хотя проблема быстрого поиска окончания пропускаемого кода остаётся), но неприменимо, если его немного усложнить, когда "100500 строк НЕ нужного кода" нужно выполнять в одних случаях, а в других не выполнять
Т.е. если усложнять пример "разумного использования", то он будет выглядеть так:
&ИзменениеИКонтроль
Функция СложныйМногоступенчатыйАлгоритмНа100500Строк()
//100500 строк нужного кода
#Вставка
Если НЕ НадоВыполнитьКусокТиповогоКода Тогда
Перейти ~ПропуститьНенужныйКод;
КонецЕсли;
#КонецВставки
//100500 строк НЕ нужного кода
#Вставка
~ПропуститьНенужныйКод:
#КонецВставки
//100500 строк нужного кода
КонецФункции
(39)Добавить Область. Вариант с "перейти" никак не исправляет ситуацию.
Если вы выкинули 100500 строк кода и решили, что они вообще никогда вам не понадобятся, то пишите "Вместо".
Те, у кого действительно есть настоящий "академический навык", знают что перейти мало чем отличается от прервать, продолжить и возврат в середине процедуры. А те, кто еще и на языке ассемблера программировал, знают, что вызов функции почти то же самое, что GOTO. Все это - "синтаксический сахар" для нарушения последовательного выполнения кода. Использование / неиспользование GOTO определяется скорее соглашениями внутри коллектива разработчиков и возможностями, предоставляемыми языком. Так, в языке 1С нет аналога цикла do...while (его надо эмулировать циклом Пока... ), нет аналога switch...case...breake (можно эмулировать каскадом процедур). Последнее предоставляет средство множественного входа в блок кода. Специального средства множественного выхода из блока кода тоже нет, но его легко получить с помощью прервать или возврат. Использовать вместо перейти try..catch, технически тоже можно, но с точки зрения методологии это самый плохой вариант, механизм исключений не для этого придуман.
Возврат по сути тоже частный случай GoTo. Заменяли код "скриптами" запускаемыми при помощи Выполнить во времена когда расширений еще не было. Приходилось все "Возврат" менять на Goto. На мой взгляд главный риск это то, что с Goto можно случайно создать бесконечный цикл, если метка стоит перед оператором.
(23)Риск с неверным расположением метки GOTO примерно аналогичен риску бесконечной рекурсии или риску изменения итератора внутри цикла Для..., или риску бесконечного цикла Пока...
(24) неверно выразился. На мой вгляд дело не в визуальном оформлении кода, а в сложности раскуриваний условий перехода. Если в случае цикла разбирать придется только внутренности Пока...Цикл..КонецЦикла, то в случае Goto все содержимое между меткой и оператором.
(27)так это же одно и то же. Есть некая область кода, ограниченная Цикл... КонецЦикла или GOTO... метка (метка ... GOTO). Она может быть большой или маленькой, но одинаково влиять (или не влиять) на условие перехода к метке или на следующую итерацию цикла.
Больная тема затронута в статье.
Тех, кто использует GoTo на ЯВУ, надо по пальцам бить. Кроме запутанности кода никакого прироста производительности на практике от него нет. Если не умеете обходиться без GoTo, то может быть лучше перестроить алгоритм или сменить профессию ?
GoTo только для низкоуровневого программирования и для прошивок микроконтроллеров.
А вот про создание собственного обфускатора с автором не согласен - пишу свой с применением самых лучших практик и добавлением своих фишек.
(31) Не надо никого бить. Даже по пальцам) Если разработчики ЯВУ включают в него GOTO, значит допускают его использование. Само по себе использование GOTO не увеличивает производительность, просто в некоторых случаях реализация алгоритмов без GOTO более сложна, о чем в статье и написано. Вопрос только в том, умеет ли программист писать качественный код с использованием GOTO, или нет. Если не умеет - то ему не следует использовать GOTO, вот и все.
Со статьей полностью согласен. Буду прописывать ее "блюстителям строгих правил".
Переходы ограничены пределами текущих областей видимости - функциями, процедурами и модулями объектов, в которых применяется оператор GOTO
Может невнимательно читал, но в статье не уловил довольно важный момент - переходы по меткам разрешены в пределах видимости и только внутри текущих конструкций языка, т.е. внутрь соседнего цикла/условия/попытки снаружи запрыгнуть нельзя.
Да. Насчитал в инструментах разработчика 9 статических и 3 генерируемых переходов по меткам. Всегда не испытывал за них стыда. Наоборот даже горжусь тем, что я умею их применять.
Если вы каждый раз не генерируете новое уникальное название, то часто программный кэш не очищается и 1С работает со старыми версиями обработок
Такая проблема была в генераторе в консоли кода ИР на платформе 8.3.11+, где изменили кэширование внешних обработок
Но я нашел ее решение. Предлагаю добавить эту информацию в статью раз уж ты решил так глубоко копнуть.
(49) выглядит как магия.
В конце недели планирую вычитать все комментарии и подправить статью - сделать акцент на то, что нельзя прыгать внутрь циклов/условий/попыток и добавить интересный код. Ну и решение с внешними обработками добавлю, раз оно есть.
(51) при подготовке статьи встречал много отсылок на Дракон. Где-то даже цитировали его разработчиков, которые утверждали, что циклы несут больший вред для алгоритмического мышления чем goto (может не такими словами, но по сути).
Но не все, кто академически занимается и программированием тоже, заканчивали какие-то кафедры (да, я там работал, но знаю и тех, кто вообще ничего не заканчивал, но они жали руки кнутам и дейкстрам направо и налево). И пункт номер РАЗ - это надуманный пункт, т.к. разные методы расчета - это функции. В части выхода из циклов, ветвлений и т.д. - полностью поддерживаю. По поводу отказа в ряде случаев от процедур и функций, то очень зыбкое такое допущение. Может быть в каком-то пограничном варианте это может привести к какой-то пользе.
Да, иногда использую "гото" для выхода из циклов и ветвлений и для того, чтобы не пилить лишний цикл на два шага (типа в последний день месяца делаем это два раза, а в остальные дни месяца - раз, тут как раз случай, когда код не выносится в процедуру, хотя можно было бы это сделать и вызвать функцию раз для дня и еще раз, если он последний в месяце, но если в функцию приходится тащить кучу локальных переменных, то пилить сто параметров или засовывать их все в структуру - это как-то убого выглядит, т.е. сильно хуже, чем "гото").
В общем, "гото" - это хорошо в некоторых случаях (как соль в еде), хотя тех, кто учился на кафедрах и не смог на достаточном уровне познать дзен-программинг, часто с "гото" плющит и колбасит. Прям как последователей чумаков, которым сказали, что вода в крещение течет заряженная с крана...
ЗЫ: Сам последний раз в 1С "гото" употреблял очень давно - года три назад. Мало в 1С сложного в последнее время требуется. А простое можно и без "гото" написать.
63.
alexey_kurdyukov
9522.02.23 09:25 Сейчас в теме
Давайте просто использовать средства там, где нужно. Если нужно Перейти - то используем Перейти, если не нужно - то не используем, а не вот это вот как маленькие бородатые девочки: "Ай миня гоуту укусиль, нильзя его использовать!"
64.
alexey_kurdyukov
9522.02.23 09:29 Сейчас в теме
А Попытка-Исключение позволяет отделить рабочую логику функции от обработки ошибки и не вкорячивать всякие флаги, спецзначения, передачу параметров из функции в аргументах и тому подобное
Согласен с автором, безусловные гонения именно против оператора GoTo ничем не лучше его бессистемного использования.
Причем, на практике заметил, что наиболее яркие противники ничего не имеют против Возврат, Продолжить или Прервать, хотя это тоже безусловные переходы, только к предопределённым точкам
(61) На самом деле есть программа ИС ДРАКОН - в ней рисуются алгоритмы, и она переносит код с алгортимов в конфигуратор в стилистике GoTo.
Тоесть в итоге я вижу графическое представление кода 1С на схеме. А код в конфигуратор, с расставлением GoTo делает сам программа. Я работаю только над логикой решения в графическом виде. Очень удобно. Делаю целые проекты так уже лет 15.
Ужас. "Лесенка" из циклов и "если" даже не намекает, а прям орёт про проблемы с кодом. Такой код надо переписывать, а не подпирать GOTO. Я бы такой код даже близко к проду не подпустил
На самом деле часто оператор перейти, если его правильно использовать, очень помогает оптимизировать код. Был случай, когда переделывал код из стандартного на код с GOTO- удалось ускорить выполнение тяжелой формы в 2 раза. Другое дело, что этот оператор надо использовать очень и очень осторожно - в пределах видимости, чтобы у следующих программистов не было проблем с поиском ошибок.