При чтении чужого или даже типового исходного кода разработчики периодически наталкиваются на конструкции, ветка выполнения которых заведомо никогда не исполнится. Самый распространенный пример выглядит так:
Организация = Выборка.Организация;
Если Ложь Тогда
Организация = Справочники.Организации.СоздатьЭлемент();
КонецЕсли;
ОрганизацияРеквизиты = "ОГРН " + Организация.ОГРН + ", ИНН/КПП " + Организация.ИНН;
На первый взгляд такой фрагмент кажется бессмысленным артефактом отладки или грубой ошибкой. Однако в среде разработки 1С за этой конструкцией скрываются конкретные приемы, обусловленные историческими особенностями платформы. Разберем подробно, для чего создаются такие блоки, как на них реагирует среда разработки, чем они опасны и как правильно решать подобные задачи сегодня.
Основная и самая популярная причина использования такой конструкции — управление механизмом контекстного автодополнения (снегопадом или штатной подсказкой Конфигуратора). В языке 1С применяется динамическая типизация. Когда переменная получает значение из универсальной коллекции, выборки запроса или реквизита формы, штатный редактор кода Конфигуратора не может заранее вычислить, объект какого типа окажется в переменной в момент исполнения программы.
Посмотрим, как устроен синтаксический анализ в стандартном Конфигураторе:
Если Ложь Тогда.Таким образом, фиктивное присваивание сообщает среде разработки точный тип метаданных (например, СправочникОбъект.Организации). В результате разработчик при вводе имени переменной и точки получает полный список доступных реквизитов, табличных частей и методов объекта, что существенно ускоряет написание кода и снижает риск опечаток.
Помимо конструкции с оператором Если, некоторые разработчики применяют схожий трюк с директивами препроцессора:
#Если Сервер И Не Сервер Тогда
Организация = Справочники.Организации.СоздатьЭлемент();
#КонецЕсли
В этом случае условие препроцессора всегда ложно при компиляции, однако редактор кода всё равно может учитывать тип присваиваемого значения, а синтаксический контроль при определенных конфигурациях не выдает предупреждений о недоступности контекста.
Вторая распространенная причина появления подобных конструкций связана с процессом сопровождения нетиповых конфигураций. При изменении типовых процедур разработчики нередко сталкиваются с необходимостью отключить исходный алгоритм и внедрить свой собственный.
Вместо привычного комментирования строк используется следующая схема:
Если Ложь Тогда
// Исходный типовой блок конфигурации поставщика
РассчитатьСкидкиПоУмолчанию(ПараметрыРасчета);
Иначе
// Доработанный пользовательский алгоритм
РассчитатьИндивидуальныеСкидки(ПараметрыРасчета);
КонецЕсли;
Рассмотрим мотивы применения такого приема:
Несмотря на кажущееся удобство, применение заведомо ложных условий порождает серьезные технические проблемы, о которых важно помнить:
Если Ложь Тогда ... КонецЕсли; компилируется в исполняемый байт-код платформы. При каждом вызове процедуры виртуальная машина тратит ресурсы на проверку условия и выполнение перехода, что создает лишнюю нагрузку на сервер.Unreachable code) и Неиспользуемое присваивание переменной.Разберем, как следует решать задачи типизации и версионирования кода в соответствии с современными стандартами разработки 1С без использования мертвых блоков.
// Параметры: с явным типом метаданных. Для локальных переменных в развитых инструментах применяются специальные директивы вида // @type ИмяТипа, которые считываются языковым сервером без внедрения фиктивных инструкций в исполняемый код.&Вместо, &Перед или &После. Это избавляет от необходимости редактировать код поставщика в основной конфигурации и полностью снимает проблему конфликтов при обновлении.