()Вот тут я с Вами не буду спорить - меня тоже терзают смутные сомнения в том, как это будет работать (особенно зная как работает сравнение текстов алгоритмов при объединении конфигураций). Я выше предложил немного более гибкое решение но и оно не идеально! Но я вообще не вижу тут идеального решения. Даже если тут макропрограммирование на полную катушку развернуть - хотя оно конечно переложит вопросы доведения результата к асимптотическому идеалу уже на руки самих конечных программистов - но простоты это не прибавит! Пока теория программирования ещё не родила парадигмы, позволяющей изящно и надёжно решать такие задачи (ну или свести их появление к асимптотическому нулю)!
Да и, одними, лишь, синтаксическими конструкциями тут не обойтись. Тут принципиально нужно менять подход к самой архитектуре логики выстраиваемых решений. То есть, нужно стремиться решать не фактическую проблему, когда нужно во так вклиниваться в алгоритм, стоящий на поддержке у другого поставщика, с сохранением этой поддержки - а решать причины, почему приходится так вклиниваться. Для приведённого в статье примера это могло бы быть решено архитектурно, вот, хочу немного пофантазировать, но сначала попробую предложить классический паттерн, например, для ООП, чтобы показать, как это может выглядеть уже сейчас или в будущем (для простоты оптимизирую только часть, обрабатываемую в исходном примере; на красоту решения не претендую):
Я напишу процедуру из примера вот так:
Вариант 1 "Фабрика классов" - навеян классическим подходом из ООП (где такое решение само по себе является костылём) с фишками из C#
функция СоздатьИнтернетПочтовоеСообщение(Контекст, Письмо, Отправитель, Назначение=неопределено, ДополнительныеПараметры=неопределено)
ИмяТипаПровайдераСообщений = ДополнительныеПараметры?.ИмяТипаПровайдераСообщений ?? "ИнтернетПочтовоеСообщение";
Сообщение = Контекст?.ФабрикаТипов.СоздатьОбъект(Контекст, ИмяТипаПровайдераСообщений, Назначение, ДополнительныеПараметры) ?? Новый ИнтернетПочтовоеСообщение();
Сообщение.Тема = Письмо.Наименование;
Сообщение.Отправитель = Отправитель;
Текст = Сообщение.Тексты.Добавить("Привет!")
Текст.ТипТекста = ТипТекстаПочтовогоСообщения.ПростойТекст;
возврат Сообщение;
КонецФункции
//При этом у нас создан свой класс-наследник от ИнтернетПочтовоеСообщение, с переопределёнными свойствами
КЛАСС СрочноеИнтернетПочтовоеСообщение(ИнтернетПочтовоеСообщение)
&Переопределить
Тема
СОБЫТИЯ
ЧТЕНИЕ
возврат РОДИТЕЛЬ.Тема+ " СРОЧНО";
КОНЕЦЧТЕНИЕ
КОНЕЦСОБЫТИЯ;
&Переопределить
Отправитель
СОБЫТИЯ
ЧТЕНИЕ
возврат РОДИТЕЛЬ.Отправитель+ " СРОЧНО";
КОНЕЦЧТЕНИЕ
КОНЕЦСОБЫТИЯ;
КонецКласса
//Данные класс зарегистрирован в нашей фабрике классов под именем "СрочноеИнтернетПочтовоеСообщение", которая хранится в контексте выполнения (упущу эти простые действия из примера)
//Тогда вызов функции будет такой
Сообщение = СоздатьИнтернетПочтовоеСообщение(Контекст, Письмо, Отправитель, , Новый Структура("ИмяТипаПровайдераСообщений", "СрочноеИнтернетПочтовоеСообщение"));
//Пояснение операций (взяты из C#):
//?. - правый оператор разыменования со встроенной проверкой на null (а для 1С ещё и на неопределено) - если операнд слева не инициализирован значением - то выражение справа не выполняется, а возвращает null (ну в 1С наверное "неопределено"). так же для динамических структурных объектов (ака "Структура") обращение к свойствам через такую операцию обеспечивает проверку их отсутствия - тогда так же будет возвращено "неопределено"
//?? - бинарный оператор - быстрая проверка на null или неопределенно - если левый операнд такой, то возвращает правый, иначе возвращает левый
Показать
Суть примера в том, что я подменяю типовой класс, на свой, с изменённой логикой и заставляю функцию использовать именно его.
Но как-то солоновато выходит - для такого простого примера.
Тогда вариант 2 "Динамическая/Статическая модификация" - навеян метапрограммированием
&РасширенноеУправление
функция СоздатьИнтернетПочтовоеСообщение(Письмо, Отправитель)
Сообщение = Новый ИнтернетПочтовоеСообщение() &МаркерПравый("НовыйИнтернетПочтовоеСообщение");
Если &ВнутреннийПараметр("СтандартнаяИнициализацияСообщения", Истина) = Истина Тогда
Сообщение.Тема = Письмо.Наименование;
Сообщение.Отправитель = Отправитель;
КонецЕсл;
Сообщение &МаркерПравый("ИнициализацияСообщения");
Текст = Сообщение.Тексты.Добавить("Привет!")
Текст.ТипТекста = ТипТекстаПочтовогоСообщения.ПростойТекст;
возврат Сообщение;
КонецФункции
//Тогда для динамического изменения мы в месте вызова данной функции создадим новую, с модификацией:
ВнутренниеПараметры = Новый Структура("СтандартнаяИнициализацияСообщения", Ложь);
НоваяФункция = МОДИФИКАЦИЯ функция СоздатьИнтернетПочтовоеСообщение
УСТАНОВКА ВнутренниеПараметры ВнутренниеПараметры
ЗАМЕНА Маркер("ИнициализацияСообщения")
Сообщение.Тема = Письмо.Наименование + " СРОЧНО";
Сообщение.Отправитель = Отправитель+ " СРОЧНО";
КОНЕЦЗАМЕНЫ
КОНЕЦМОДИФИКАЦИИ
//ну и выполняем уже модифицированную функцию
Сообщение = НоваяФункция(Письмо, Отправитель);
Показать
Тоже нельзя сказать, что вариант 2 выглядит красиво
Его статическая версия - не создаёт новую функцию - а модифицирует исходную (или создаёт новую, на основе исходной, но тоже статически) в специальном модуле статического выполнения макрофункций (выполняемого только в момент компиляции)
Поэтому вариант 3
&РасширенноеУправление
функция СоздатьИнтернетПочтовоеСообщение(Письмо, Отправитель)
Сообщение = &ВнутреннийПараметр("ИмяТипаПровайдераСообщений", Новый ИнтернетПочтовоеСообщение());
Если &ВнутреннийПараметр("СтандартнаяИнициализацияСообщения", Истина) = Истина Тогда
Сообщение.Тема = Письмо.Наименование;
Сообщение.Отправитель = Отправитель;
КонецЕсл;
ВЫЗВАТЬФУНКЦИЮ(&ВнутреннийПараметр("ИнициализацияСообщения"), Новый Структура("Сообщение, Письмо, Отправитель", Сообщение, Письмо, Отправитель)));
Текст = Сообщение.Тексты.Добавить("Привет!")
Текст.ТипТекста = ТипТекстаПочтовогоСообщения.ПростойТекст;
возврат Сообщение;
КонецФункции
функция ОбработкаСообщений(Сообщение, Письмо, Отправитель) экспорт
Сообщение.Тема = Письмо.Наименование + " СРОЧНО";
Сообщение.Отправитель = Отправитель+ " СРОЧНО";
возврат неопределено;
КонецФункции
ВнутренниеПараметры = Новый Структура("СтандартнаяИнициализацияСообщения, ИнициализацияСообщения", Ложь, @ОбработкаСообщений); //@ОбработкаСообщений - это ссылка на функцию
Сообщение = СоздатьИнтернетПочтовоеСообщение(Письмо, Отправитель) СПАРАМЕТРАМИВЫПОЛНЕНИЯ(ВнутренниеПараметры);
Показать
В данном примере частично совмещены варианты 1 и 2 с одной стороны - я вынес за пределы нашей функции функционал как выбор типа объекта-провайдера сообщений, так и алгоритм модификации заголовка сообщения, с другой так же ввел макроуправление - встроенные параметры функции (которые не передаются через аргументы функции, хотя такую передачу так же можно было бы сделать без всяких макрохитростей)
Теперь это выглядит более-менее красиво!
Но я повторюсь, я не претендую на красоту данных примеров - я просто намекаю на то, что проблема лежит не только в области синтаксиса языка, но и в области архитектуры построения самих алгоритмов.
Ну и как бы эту архитектуру правильно не выстраивали – всё равно будут случаи, когда нужно будет что-то вставить своё в эту типовую архитектуру в месте, где это в ней никак не предусмотрено!