From 97abd05fb3cf53e53f6743c03b860bae1548614b Mon Sep 17 00:00:00 2001 From: sfaqer Date: Tue, 29 Sep 2026 20:07:05 +1000 Subject: [PATCH 1/3] =?UTF-8?q?fix:=20=D0=BF=D0=BE=D1=82=D0=BE=D0=BA=D0=BE?= =?UTF-8?q?=D0=B1=D0=B5=D0=B7=D0=BE=D0=BF=D0=B0=D1=81=D0=BD=D1=8B=D0=B9=20?= =?UTF-8?q?=D0=B8=D0=BD=D0=B4=D0=B5=D0=BA=D1=81=20=D0=BF=D0=B0=D1=80=D0=B0?= =?UTF-8?q?=D0=BC=D0=B5=D1=82=D1=80=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Индекс строился заново на каждый вызов Параметр() в общее поле экземпляра, из-за чего параллельные вызовы из фоновых заданий падали с исключениями Dictionary и возвращали пустые или чужие значения. - ИндексЗначений строит индекс в локальную карту в Коллекция() и публикует его одним присваиванием поля; чтение идет без блокировок - Прочитать() больше не очищает индекс заранее: новый индекс подменяет прежний только после полного построения - исправлено исключение "Коллекция индекса не установлена" (Новый ИнформацияОбОшибке в 2.x не создается) - документирован контракт многопоточности и ПрочитанныеПараметры() - тесты на однократное построение и параллельное чтение Co-Authored-By: Claude Opus 5.5 --- docs/README.md | 6 + ...21\207\320\265\320\275\320\270\320\271.os" | 76 +++--- ...20\265\321\202\321\200\320\276\320\262.os" | 7 +- ...7\320\265\320\275\320\270\320\271_test.os" | 222 ++++++++++++++++++ 4 files changed, 276 insertions(+), 35 deletions(-) create mode 100644 "tests/\320\230\320\275\320\264\320\265\320\272\321\201\320\227\320\275\320\260\321\207\320\265\320\275\320\270\320\271_test.os" diff --git a/docs/README.md b/docs/README.md index f0bfd63..5de3637 100644 --- a/docs/README.md +++ b/docs/README.md @@ -60,6 +60,7 @@ #### Параметр ```bsl // Получает и возвращает значение из индекса параметров +// Индекс строится один раз в Прочитать(), чтение потокобезопасно и выполняется без блокировок // // Параметры: // ИмяПараметра - Строка - имя параметра @@ -85,6 +86,8 @@ #### ПрочитанныеПараметры ```bsl // Возвращает соответствие прочитанных параметров (сырой результат без обработки конструктором) +// Изменения возвращенного соответствия не попадают в Параметр(): индекс параметров +// строится в Прочитать(), для применения изменений нужно повторно вызвать Прочитать() // // Возвращаемое значение: // Соответствие - прочитанные параметры @@ -95,6 +98,9 @@ #### Прочитать ```bsl // Выполняет чтения параметров из доступных провайдеров +// Новый индекс параметров строится полностью и только потом подменяет прежний, +// поэтому Параметр() можно вызывать параллельно с Прочитать(): до подмены читается прежний индекс. +// Параллельные вызовы Прочитать() между собой не поддерживаются // ``` diff --git "a/src/\320\232\320\273\320\260\321\201\321\201\321\213/internal/\320\232\320\273\320\260\321\201\321\201\321\213/\320\230\320\275\320\264\320\265\320\272\321\201\320\227\320\275\320\260\321\207\320\265\320\275\320\270\320\271.os" "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/internal/\320\232\320\273\320\260\321\201\321\201\321\213/\320\230\320\275\320\264\320\265\320\272\321\201\320\227\320\275\320\260\321\207\320\265\320\275\320\270\320\271.os" index 540d977..a45e4c9 100644 --- "a/src/\320\232\320\273\320\260\321\201\321\201\321\213/internal/\320\232\320\273\320\260\321\201\321\201\321\213/\320\230\320\275\320\264\320\265\320\272\321\201\320\227\320\275\320\260\321\207\320\265\320\275\320\270\320\271.os" +++ "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/internal/\320\232\320\273\320\260\321\201\321\201\321\213/\320\230\320\275\320\264\320\265\320\272\321\201\320\227\320\275\320\260\321\207\320\265\320\275\320\270\320\271.os" @@ -2,14 +2,16 @@ #Использовать logos Перем Лог; -Перем ИндексКоллекция; // Соответствие -Перем ИндексСформирован; // Булево -Перем КоллекцияИндекса; // Произвольный +Перем ИндексКоллекция; // Соответствие - опубликованный индекс, Неопределено - коллекция не установлена. + // Строится целиком в локальную карту и публикуется одним присваиванием, + // после публикации не изменяется: читается без блокировок из любых потоков Функция Коллекция(Знач ВходящаяКоллекция) Экспорт - КоллекцияИндекса = ВходящаяКоллекция; - ИндексСформирован = Ложь; + НовыйИндекс = ПостроитьИндекс(ВходящаяКоллекция); + + // Читатели видят либо прежний индекс, либо новый целиком + ИндексКоллекция = НовыйИндекс; Возврат ЭтотОбъект; @@ -17,53 +19,59 @@ Процедура Очистить() Экспорт - КоллекцияИндекса = Неопределено; - ИндексСформирован = Ложь; + ИндексКоллекция = Неопределено; КонецПроцедуры +// Возвращает опубликованный индекс. Индекс общий для всех потоков, изменять его нельзя +// +// Возвращаемое значение: +// Соответствие - плоский индекс значений коллекции +// Функция ПолучитьИндекс() Экспорт - ПроверитьИндекс(); - - Возврат ИндексКоллекция; + Возврат ОпубликованныйИндекс(); КонецФункции Функция Значение(Знач КлючИндекса) Экспорт - ПроверитьИндекс(); + Индекс = ОпубликованныйИндекс(); Если ТипЗнч(КлючИндекса) = Тип("Строка") Тогда КлючИндекса = НРег(КлючИндекса); КонецЕсли; - ЗначениеИзИндекса = ИндексКоллекция[КлючИндекса]; + ЗначениеИзИндекса = Индекс[КлючИндекса]; Возврат ЗначениеИзИндекса; КонецФункции -Процедура СформироватьИндекс() +Функция ПостроитьИндекс(Знач ИсходнаяКоллекция) - ИндексКоллекция = Новый Соответствие; + Индекс = Новый Соответствие; // Рекурсивный вызов для входящих параметров - ДобавитьЗначениеПараметра("", КоллекцияИндекса); + ДобавитьЗначениеПараметра(Индекс, "", ИсходнаяКоллекция); -КонецПроцедуры + Возврат Индекс; -Процедура ПроверитьИндекс() +КонецФункции - Если КоллекцияИндекса = Неопределено Тогда - ВызватьИсключение Новый ИнформацияОбОшибке("Коллекция индекса не установлена"); - КонецЕсли; +// Поле читается один раз, дальше работа идет с локальной ссылкой, +// которую не подменят параллельные Коллекция() и Очистить() +Функция ОпубликованныйИндекс() - Если НЕ ИндексСформирован Тогда - СформироватьИндекс(); + Индекс = ИндексКоллекция; + + Если Индекс = Неопределено Тогда + ВызватьИсключение "Коллекция индекса не установлена"; КонецЕсли; + + Возврат Индекс; -КонецПроцедуры +КонецФункции Функция ЭтоМассив(Знач Значение) Возврат ТипЗнч(Значение) = Тип("Массив"); @@ -81,7 +89,7 @@ Возврат ТипЗнч(Значение) = Тип("Сценарий"); КонецФункции -Процедура ДобавитьПараметрВИндекс(Знач ИмяПараметра, Знач ЗначениеПараметра) +Процедура ДобавитьПараметрВИндекс(Индекс, Знач ИмяПараметра, Знач ЗначениеПараметра) // Вставляем все значение целиком Если Не ПустаяСтрока(ИмяПараметра) Тогда @@ -91,27 +99,27 @@ ИмяПараметра = НРег(ИмяПараметра); КонецЕсли; - ИндексКоллекция.Вставить(ИмяПараметра, ЗначениеПараметра); + Индекс.Вставить(ИмяПараметра, ЗначениеПараметра); КонецЕсли; // Рекурсивное заполнение значения параметра - ДобавитьЗначениеПараметра(ИмяПараметра, ЗначениеПараметра); + ДобавитьЗначениеПараметра(Индекс, ИмяПараметра, ЗначениеПараметра); КонецПроцедуры -Процедура ДобавитьЗначениеПараметра(Знач ИмяПараметра, Знач ЗначениеПараметра) +Процедура ДобавитьЗначениеПараметра(Индекс, Знач ИмяПараметра, Знач ЗначениеПараметра) Если ЭтоМассив(ЗначениеПараметра) Тогда - ДобавитьПараметрМассивВИндекс(ЗначениеПараметра, ИмяПараметра); + ДобавитьПараметрМассивВИндекс(Индекс, ЗначениеПараметра, ИмяПараметра); ИначеЕсли ЭтоСоответствие(ЗначениеПараметра) Тогда - ДобавитьСоответствиеВИндекс(ЗначениеПараметра, ИмяПараметра); + ДобавитьСоответствиеВИндекс(Индекс, ЗначениеПараметра, ИмяПараметра); ИначеЕсли ЭтоСтруктура(ЗначениеПараметра) Тогда - ДобавитьСоответствиеВИндекс(ЗначениеПараметра, ИмяПараметра); + ДобавитьСоответствиеВИндекс(Индекс, ЗначениеПараметра, ИмяПараметра); КонецЕсли; КонецПроцедуры -Процедура ДобавитьПараметрМассивВИндекс(Знач МассивЗначений, Знач ИмяРодителя = "") +Процедура ДобавитьПараметрМассивВИндекс(Индекс, Знач МассивЗначений, Знач ИмяРодителя = "") Лог.Отладка("Обрабатываю массив значений <%1> ", ИмяРодителя); @@ -124,13 +132,13 @@ Для ИндексЗначения = 0 По МассивЗначений.ВГраница() Цикл ИмяПараметра = СтрШаблон(ШаблонИмениПараметра, ИндексЗначения); - ДобавитьПараметрВИндекс(ИмяПараметра, МассивЗначений[ИндексЗначения]); + ДобавитьПараметрВИндекс(Индекс, ИмяПараметра, МассивЗначений[ИндексЗначения]); КонецЦикла; КонецПроцедуры -Процедура ДобавитьСоответствиеВИндекс(Знач ВходящиеПараметры, Знач ИмяРодителя = "") +Процедура ДобавитьСоответствиеВИндекс(Индекс, Знач ВходящиеПараметры, Знач ИмяРодителя = "") Лог.Отладка("Обрабатываю соответствие значений <%1> ", ИмяРодителя); @@ -147,7 +155,7 @@ ИмяПараметра = СтрШаблон(ШаблонИмениПараметра, КлючЗначение.Ключ); ЗначениеПараметра = КлючЗначение.Значение; - ДобавитьПараметрВИндекс(ИмяПараметра, ЗначениеПараметра); + ДобавитьПараметрВИндекс(Индекс, ИмяПараметра, ЗначениеПараметра); КонецЦикла; diff --git "a/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\234\320\265\320\275\320\265\320\264\320\266\320\265\321\200\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\320\276\320\262.os" "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\234\320\265\320\275\320\265\320\264\320\266\320\265\321\200\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\320\276\320\262.os" index 273f5a2..94d4921 100644 --- "a/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\234\320\265\320\275\320\265\320\264\320\266\320\265\321\200\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\320\276\320\262.os" +++ "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\234\320\265\320\275\320\265\320\264\320\266\320\265\321\200\320\237\320\260\321\200\320\260\320\274\320\265\321\202\321\200\320\276\320\262.os" @@ -24,6 +24,7 @@ #Область Экспортных_процедур // Получает и возвращает значение из индекса параметров +// Индекс строится один раз в Прочитать(), чтение потокобезопасно и выполняется без блокировок // // Параметры: // ИмяПараметра - Строка - имя параметра @@ -55,6 +56,8 @@ КонецФункции // Возвращает соответствие прочитанных параметров +// Изменения возвращенного соответствия не попадают в Параметр(): индекс параметров +// строится в Прочитать(), для применения изменений нужно повторно вызвать Прочитать() // // Возвращаемое значение: // Соответствие - прочитанные параметров @@ -64,10 +67,12 @@ КонецФункции // Выполняет чтения параметров из доступных провайдеров +// Новый индекс параметров строится полностью и только потом подменяет прежний, +// поэтому Параметр() можно вызывать параллельно с Прочитать(): до подмены читается прежний индекс. +// Параллельные вызовы Прочитать() между собой не поддерживаются // Процедура Прочитать() Экспорт - ИндексПараметров.Очистить(); ПрочитанныеПараметры.Очистить(); ВыполнитьЧтениеПровайдеров(); diff --git "a/tests/\320\230\320\275\320\264\320\265\320\272\321\201\320\227\320\275\320\260\321\207\320\265\320\275\320\270\320\271_test.os" "b/tests/\320\230\320\275\320\264\320\265\320\272\321\201\320\227\320\275\320\260\321\207\320\265\320\275\320\270\320\271_test.os" new file mode 100644 index 0000000..91a7013 --- /dev/null +++ "b/tests/\320\230\320\275\320\264\320\265\320\272\321\201\320\227\320\275\320\260\321\207\320\265\320\275\320\270\320\271_test.os" @@ -0,0 +1,222 @@ +#использовать "../src/" +#Использовать asserts + +Перем КоличествоКлючей; // Число - количество параметров в тестовом источнике +Перем КоличествоЗаданий; // Число - количество параллельных фоновых заданий +Перем КоличествоЧтений; // Число - количество вызовов Параметр() в каждом задании +Перем КоличествоПеречитываний; // Число - количество вызовов Прочитать() во время параллельного чтения + +&Тест +Процедура ТестДолжен_ПостроитьИндексОдинРазДляКоллекции() Экспорт + + // Дано + Индекс = Новый ИндексЗначений; + Индекс.Коллекция(ТестовыеПараметры()); + + // Когда + ПервыйИндекс = Индекс.ПолучитьИндекс(); + Индекс.Значение("key1.value"); + ВторойИндекс = Индекс.ПолучитьИндекс(); + + Индекс.Коллекция(ТестовыеПараметры()); + ИндексНовойКоллекции = Индекс.ПолучитьИндекс(); + + // Тогда + Ожидаем.Что(ПервыйИндекс = ВторойИндекс, "Повторное чтение не должно пересобирать индекс").ЭтоИстина(); + Ожидаем.Что(ИндексНовойКоллекции = ПервыйИндекс, "Новая коллекция должна дать новый индекс").ЭтоЛожь(); + Ожидаем.Что(Индекс.Значение("KEY1.Value")).Равно("значение1"); + +КонецПроцедуры + +&Тест +Процедура ТестДолжен_ПерестроитьИндексМенеджераПослеПрочитать() Экспорт + + // Дано + МенеджерПараметров = НовыйМенеджерПараметров(); + ИндексПараметров = Новый Рефлектор().ПолучитьСвойство(МенеджерПараметров, "ИндексПараметров"); + + // Когда + ПервыйИндекс = ИндексПараметров.ПолучитьИндекс(); + МенеджерПараметров.Параметр("key1.value"); + ВторойИндекс = ИндексПараметров.ПолучитьИндекс(); + + МенеджерПараметров.Прочитать(); + ИндексПослеПрочитать = ИндексПараметров.ПолучитьИндекс(); + + // Тогда + Ожидаем.Что(ПервыйИндекс = ВторойИндекс, "Параметр() не должен пересобирать индекс").ЭтоИстина(); + Ожидаем.Что(ИндексПослеПрочитать = ПервыйИндекс, "Прочитать() должен построить новый индекс").ЭтоЛожь(); + Ожидаем.Что(МенеджерПараметров.Параметр("key1.value")).Равно("значение1"); + +КонецПроцедуры + +&Тест +Процедура ТестДолжен_ВызватьИсключениеПослеОчисткиИндекса() Экспорт + + // Дано + Индекс = Новый ИндексЗначений; + Индекс.Коллекция(ТестовыеПараметры()); + + // Когда + Индекс.Очистить(); + + // Тогда + БылоИсключение = Ложь; + Попытка + Индекс.Значение("key1.value"); + Исключение + БылоИсключение = Истина; + Ожидаем.Что(ИнформацияОбОшибке().Описание).Содержит("Коллекция индекса не установлена"); + КонецПопытки; + + Ожидаем.Что(БылоИсключение, "После очистки индекс недоступен").ЭтоИстина(); + +КонецПроцедуры + +&Тест +Процедура ТестДолжен_ПараллельноЧитатьПараметрыБезОшибок() Экспорт + + // Дано + МенеджерПараметров = НовыйМенеджерПараметров(); + + // Когда + Задания = Новый Массив; + Для НомерЗадания = 1 По КоличествоЗаданий Цикл + Задания.Добавить(ЗапуститьЧтениеПараметров(МенеджерПараметров, НомерЗадания)); + КонецЦикла; + + // Тогда + ПроверитьОтсутствиеОшибок(Задания); + +КонецПроцедуры + +&Тест +Процедура ТестДолжен_ЧитатьПараметрыПараллельноСПрочитать() Экспорт + + // Дано + МенеджерПараметров = НовыйМенеджерПараметров(); + + // Когда + Задания = Новый Массив; + Для НомерЗадания = 1 По КоличествоЗаданий Цикл + Задания.Добавить(ЗапуститьЧтениеПараметров(МенеджерПараметров, НомерЗадания)); + КонецЦикла; + + ПараметрыЗадания = Новый Массив; + ПараметрыЗадания.Добавить(МенеджерПараметров); + Задания.Добавить(ФоновыеЗадания.Выполнить(ЭтотОбъект, "ПеречитыватьПараметры", ПараметрыЗадания, Истина)); + + // Тогда + ПроверитьОтсутствиеОшибок(Задания); + +КонецПроцедуры + +#Область Фоновые_задания + +Процедура ЧитатьПараметры(Знач МенеджерПараметров, Знач НомерЗадания) Экспорт + + Ошибки = Новый Массив; + + Для НомерЧтения = 1 По КоличествоЧтений Цикл + + НомерКлюча = (НомерЗадания + НомерЧтения) % КоличествоКлючей + 1; + ИмяПараметра = СтрШаблон("key%1.value", НомерКлюча); + ОжидаемоеЗначение = СтрШаблон("значение%1", НомерКлюча); + + Попытка + Значение = МенеджерПараметров.Параметр(ИмяПараметра); + Исключение + Ошибки.Добавить(СтрШаблон("%1: %2", ИмяПараметра, КраткоеПредставлениеОшибки(ИнформацияОбОшибке()))); + Продолжить; + КонецПопытки; + + Если Значение <> ОжидаемоеЗначение Тогда + Ошибки.Добавить(СтрШаблон("%1: ожидалось <%2>, получено <%3>", ИмяПараметра, ОжидаемоеЗначение, Значение)); + КонецЕсли; + + КонецЦикла; + + Если Ошибки.Количество() > 0 Тогда + ВызватьИсключение СтрШаблон("Ошибок чтения %1 из %2, первая: %3", + Ошибки.Количество(), КоличествоЧтений, Ошибки[0]); + КонецЕсли; + +КонецПроцедуры + +Процедура ПеречитыватьПараметры(Знач МенеджерПараметров) Экспорт + + Для НомерЧтения = 1 По КоличествоПеречитываний Цикл + МенеджерПараметров.Прочитать(); + КонецЦикла; + +КонецПроцедуры + +#КонецОбласти + +#Область Вспомогательные_процедуры_и_функции + +Функция ЗапуститьЧтениеПараметров(МенеджерПараметров, НомерЗадания) + + ПараметрыЗадания = Новый Массив; + ПараметрыЗадания.Добавить(МенеджерПараметров); + ПараметрыЗадания.Добавить(НомерЗадания); + + Возврат ФоновыеЗадания.Выполнить(ЭтотОбъект, "ЧитатьПараметры", ПараметрыЗадания, Истина); + +КонецФункции + +Процедура ПроверитьОтсутствиеОшибок(Задания) + + Ошибки = Новый Массив; + + Для Каждого Задание Из Задания Цикл + + Если НЕ Задание.ОжидатьЗавершения(60000) Тогда + ВызватьИсключение "Фоновое задание не завершилось за 60 секунд"; + КонецЕсли; + + Если Задание.ИнформацияОбОшибке <> Неопределено Тогда + Ошибки.Добавить(КраткоеПредставлениеОшибки(Задание.ИнформацияОбОшибке)); + КонецЕсли; + + КонецЦикла; + + Ожидаем.Что(Ошибки.Количество(), + СтрШаблон("Заданий с ошибками %1 из %2:%3%4", Ошибки.Количество(), Задания.Количество(), + Символы.ПС, СтрСоединить(Ошибки, Символы.ПС))).Равно(0); + +КонецПроцедуры + +Функция НовыйМенеджерПараметров() + + МенеджерПараметров = Новый МенеджерПараметров(); + МенеджерПараметров.ДобавитьПровайдерПараметров(Новый ПровайдерПараметровСоответствие(ТестовыеПараметры())); + МенеджерПараметров.Прочитать(); + + Возврат МенеджерПараметров; + +КонецФункции + +Функция ТестовыеПараметры() + + Параметры = Новый Соответствие; + + Для НомерКлюча = 1 По КоличествоКлючей Цикл + + ВложенныеПараметры = Новый Соответствие; + ВложенныеПараметры.Вставить("value", СтрШаблон("значение%1", НомерКлюча)); + + Параметры.Вставить(СтрШаблон("key%1", НомерКлюча), ВложенныеПараметры); + + КонецЦикла; + + Возврат Параметры; + +КонецФункции + +#КонецОбласти + +КоличествоКлючей = 50; +КоличествоЗаданий = 32; +КоличествоЧтений = 200; +КоличествоПеречитываний = 50; From 5a5749c642f45ca58fea5f20f93e3e272100d7a9 Mon Sep 17 00:00:00 2001 From: sfaqer Date: Tue, 29 Sep 2026 20:07:05 +1000 Subject: [PATCH 2/3] =?UTF-8?q?=D0=92=D0=B5=D1=80=D1=81=D0=B8=D1=8F=200.12?= =?UTF-8?q?.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 --- packagedef | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packagedef b/packagedef index 8613d52..ca5d2c3 100644 --- a/packagedef +++ b/packagedef @@ -4,7 +4,7 @@ // Описание.Имя("configor") - .Версия("0.12.0") + .Версия("0.12.1") .Автор("Khorev Aleksey") .АдресАвтора("Khorevaa@gmail.com") .Описание("Библиотека для работы с конфигурационными файлами в формате json, yaml") From d4b12d921de56b22104fd90558b2a94bdf0c4c61 Mon Sep 17 00:00:00 2001 From: sfaqer Date: Tue, 29 Sep 2026 20:36:52 +1000 Subject: [PATCH 3/3] =?UTF-8?q?=D0=97=D0=B0=D0=BC=D0=B5=D1=87=D0=B0=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F=20Sonar=20=D0=BF=D0=BE=20=D0=98=D0=BD=D0=B4=D0=B5?= =?UTF-8?q?=D0=BA=D1=81=D0=97=D0=BD=D0=B0=D1=87=D0=B5=D0=BD=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - описание возвращаемого значения ОпубликованныйИндекс() - объединены одинаковые ветки для Соответствие и Структура Co-Authored-By: Claude Opus 5.5 --- ...75\320\260\321\207\320\265\320\275\320\270\320\271.os" | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git "a/src/\320\232\320\273\320\260\321\201\321\201\321\213/internal/\320\232\320\273\320\260\321\201\321\201\321\213/\320\230\320\275\320\264\320\265\320\272\321\201\320\227\320\275\320\260\321\207\320\265\320\275\320\270\320\271.os" "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/internal/\320\232\320\273\320\260\321\201\321\201\321\213/\320\230\320\275\320\264\320\265\320\272\321\201\320\227\320\275\320\260\321\207\320\265\320\275\320\270\320\271.os" index a45e4c9..507d96a 100644 --- "a/src/\320\232\320\273\320\260\321\201\321\201\321\213/internal/\320\232\320\273\320\260\321\201\321\201\321\213/\320\230\320\275\320\264\320\265\320\272\321\201\320\227\320\275\320\260\321\207\320\265\320\275\320\270\320\271.os" +++ "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/internal/\320\232\320\273\320\260\321\201\321\201\321\213/\320\230\320\275\320\264\320\265\320\272\321\201\320\227\320\275\320\260\321\207\320\265\320\275\320\270\320\271.os" @@ -61,6 +61,10 @@ // Поле читается один раз, дальше работа идет с локальной ссылкой, // которую не подменят параллельные Коллекция() и Очистить() +// +// Возвращаемое значение: +// Соответствие - опубликованный индекс +// Функция ОпубликованныйИндекс() Индекс = ИндексКоллекция; @@ -111,9 +115,7 @@ Если ЭтоМассив(ЗначениеПараметра) Тогда ДобавитьПараметрМассивВИндекс(Индекс, ЗначениеПараметра, ИмяПараметра); - ИначеЕсли ЭтоСоответствие(ЗначениеПараметра) Тогда - ДобавитьСоответствиеВИндекс(Индекс, ЗначениеПараметра, ИмяПараметра); - ИначеЕсли ЭтоСтруктура(ЗначениеПараметра) Тогда + ИначеЕсли ЭтоСоответствие(ЗначениеПараметра) Или ЭтоСтруктура(ЗначениеПараметра) Тогда ДобавитьСоответствиеВИндекс(Индекс, ЗначениеПараметра, ИмяПараметра); КонецЕсли;