Видимость переменных - неклассический подходКак-то все программисты уже привыкли, что переменные бывают только локальными или глобальными.
Мы расширим понятие видимости переменных и покажем, как смоделировать такую видимость во встроенном языке, а затем покажем, где такое можно применять. | | Автор статьи: Гений 1С | Редакторы: Последняя редакция №3 от 18.07.06 | История URL: http://kb.mista.ru/article.php?id=299 | |
Ключевые слова: видимость
Было бы неплохо, если бы в текущем контексте выполнения кода функции были видны не только глобальные переменные и локальные переменные текущей функции, но и переменные функций, из которой была вызывана данная.
Посмотрите на пример, как выглядел бы код. В функции Ф4 видны все переменные, объявленные в предыдущих вызовах (при этом переменные с одинаковым именем замещаются):
Функция Ф1(А,Б,В)
Сообщить(А, Б, В); //1,2,0
Ф2(В=3, Г=4); //В замещается на 3
Ф3(Г=6); //Должно передаться исходное В=0
КонецФункции
Функция Ф2(В, Г)
Сообщить(А, Б, В, Г); //1,2,3,4
КонецФункции
Функция Ф3(В, Г)
Сообщить(А, Б, В, Г); //1,2,5,6
КонецФункции
Ф1(А=1, Б=2, В=0);
В 1С это можно смоделировать так:
Функция обПрм(Родитель, Ребенок) Экспорт
Ребенок.Вставить("Родитель", Родитель);
Возврат Ребенок;
КонецФункции
Функция обСвойство(П, Параметр, Зн)
Перем Родитель;
Если НЕ П.Свойство(Параметр, Зн) Тогда
Если НЕ П.Свойство("Родитель", Родитель) Тогда
Возврат ложь;
Иначе
Возврат обДоступСвойство(Родитель, Параметр, Зн);
КонецЕсли;
Иначе
Возврат истина;
КонецЕсли;
КонецФункции
Функция обЗначение(П, Параметр, ЗнН=Неопределено)
Перем Зн;
Если обСвойство(П, Параметр, Зн) Тогда
Возврат Зн;
Иначе
Возврат ЗнН;
КонецЕсли;
КонецФункции
Тогда наш код будет выглядеть так:
Функция Ф1(П)
Сообщить(обЗначение(П,"А"), обЗначение(П,"Б")); //1,2
Ф2(обПрм(П, Новый Структура("В, Г", 3, 4)));
Ф3(обПрм(П, Новый Структура("Г", 6)));
Ф3(В=5, Г=6);
КонецФункции
Функция Ф2(П)
Сообщить(обЗначение(П,"А"), обЗначение(П,"Б"), обЗначение(П,"В"), обЗначение(П,"Г")); //1,2,3,4
КонецФункции
Функция Ф3(П)
Сообщить(обЗначение(П,"А"), обЗначение(П,"Б"), обЗначение(П,"В"), обЗначение(П,"Г")); //1,2,0,6
КонецФункции
Ф1(Новый Структура("А,Б,В", 1,2,0);
О практическом применении - расмотрим пример проверки правильности (валидности) объекта.
Часто нужно проверять правильность объекта. Но для проверки правильности объекта нужно знать не только сам объект, но и в каком контексте рассматривается проверка. Например, для проведения документ должен быть полностью заполнен, а для записи допускается частичная незаполненность. В то же время при проверке реквизита нужно не допускать неправильных значений у реквизита.
Пусть у нас есть функция Валидность(Объект, ПолнаяПроверка, ЧтоПроверять, Ошибки) которая возвращает Истину, если объект правильный и ложь, если неправильный. В случае, если есть ошибки, они накапливаются в массиве Ошибки.
При записи объекта определяем, нужна ли полная проверка (зависит от режима записи - если проведение, тогда нужна, если просто запись, тогда не нужна) и вызываем функцию с параметрами:
Валидность({Объект, ПолнаяПроверка, ЧтоПроверять="Объект"})
После выбора нового значения реквизита в форме объекта мы вызываем ту же функцию с параметрами:
Валидность({Объект, ПолнаяПроверка=ложь, ЧтоПроверять="Реквизит", Реквизит=[Имя реквизита], Значение=[Новое значение реквизита]})
Но по сути полная проверка объекта заключается в проверке валидности его строк и реквизитов этих строк.
Т.е. валидность при проверке объекта вызывает сама же себя с проверкой строк табличных частей и реквизитов. Но при этом значения ПолнаяПроверка и Объект не меняются.
Т.е. из вызова проверки валидности для объекта делаются примерно такие вызовы:
Валидность(обПрм(П, {ЧтоПроверять="Реквизит", Реквизит=[Имя реквизита], Значение=[Значение реквизита]})
Валидность(обПрм(П, {ЧтоПроверять="Строка", Строка=[Строка табличной части]})
В конце смотрим, есть ли ошибки и если они есть, возвращаем ложь - объект не валиден, содержит ошибки.
Вот здесь мы и видим, что удобно применение нашей схемы, иначе бы переменная ЧтоПроверять затиралась и нам приходилось бы ее восстанавливать.
Данный метод удобен и в других случаях, когда нужно передавать рекурсивно какие-нибудь структуры и списки.
|