Использование YAML в отладке


Пример использования YAML вывода отладочной информации

Все мы для отладки (да и не только) используем вывод некоторой иногда полезной информации. Как правило, используется старое доброе «Сообщить». Обычно это выглядит вот так:

СписокВидовДокументов = Новый Массив;
СписокВидовДокументов.Добавить("ПоступлениеТоваровУслуг");
СписокВидовДокументов.Добавить("РеализацияТоваровУслуг");
СписокВидовДокументов.Добавить("ПеремещениеТоваров");

Для Каждого мВидДокумента Из СписокВидовДокументов Цикл

Сообщить("Обрабатывается " + мВидДокумента);

Выборка = ПолучитьНекоторуюВыборку(мВидДокумента);
Пока Выборка.Следующий() Цикл

Сообщить("Обрабатывается документ: " + Выборка.Ссылка);

КонецЦикла;

КонецЦикла;

Результат:

Обрабатывается ПоступлениеТоваровУслуг
Обрабатывается документ: Поступление товаров и услуг 00000000016 от 29.10.2012 12:00:04
Обрабатывается документ: Поступление товаров и услуг 00000000017 от 27.11.2012 18:11:02
Обрабатывается документ: Поступление товаров и услуг 00000000018 от 27.11.2012 18:11:03
Обрабатывается документ: Поступление товаров и услуг 00000000019 от 27.11.2012 18:11:04
....
Обрабатывается РеализацияТоваровУслуг
Обрабатывается документ: Реализация товаров и услуг 00000000001 от 29.11.2012 17:18:12
....
Обрабатывается ПеремещениеТоваров
Обрабатывается документ: Перемещение товаров 00000000024 от 06.12.2012 17:51:27
Обрабатывается документ: Перемещение товаров 00000000033 от 12.12.2012 17:22:06
....

И всё хорошо, все рады, всё видно — можно кинуть сообщения начальнику, чтоб знал, какие документы были обработаны. Но можно сделать эту информацию чуточку удобнее:

СписокВидовДокументов = Новый Массив;
СписокВидовДокументов.Добавить("ПоступлениеТоваровУслуг");
СписокВидовДокументов.Добавить("РеализацияТоваровУслуг");
СписокВидовДокументов.Добавить("ПеремещениеТоваров");

Для Каждого мВидДокумента Из СписокВидовДокументов Цикл

Сообщить("- Обрабатывается " + мВидДокумента);

Выборка = ПолучитьНекоторуюВыборку(мВидДокумента);
Пока Выборка.Следующий() Цикл

Сообщить("  - " + Выборка.Ссылка);

КонецЦикла;

КонецЦикла;

В результате чего получим следующий вывод:

 

- Обрабатывается ПоступлениеТоваровУслуг
- Поступление товаров и услуг 00000000016 от 29.10.2012 12:00:04
- Поступление товаров и услуг 00000000017 от 27.11.2012 18:11:02
- Поступление товаров и услуг 00000000018 от 27.11.2012 18:11:03
- Поступление товаров и услуг 00000000019 от 27.11.2012 18:11:04
.....
- Обрабатывается РеализацияТоваровУслуг
- Реализация товаров и услуг 00000000001 от 29.11.2012 17:18:12
.....
- Обрабатывается ПеремещениеТоваров
- Перемещение товаров 00000000024 от 06.12.2012 17:51:27
- Перемещение товаров 00000000033 от 12.12.2012 17:22:06
- Перемещение товаров 00000000036 от 18.12.2012 16:46:44
.....

 

Копипастим сие дело в Notepad++ (искренне надеюсь, что нечто подобное стоит у многих), включаем синтаксис YAML и видим:

npp_yaml_output

 

Основное преимущество YAML в том, что это по сути просто текст, но с минимально необходимой разметкой. Что делает его удобным для отладочного вывода? То, что в нём нет закрывающих тэгов: т.е., всё, что вы уже подали на вывод, является верно размеченным текстом. Это особенно важно, когда процесс прерывается по Ctrl+Break или по исключению.

Безусловно, реализация всего стандарта целиком — дело довольно муторное, но я думаю, редкий человек будет заниматься в 1С использованием YAML вместо XML в боевых целях. Маленькое несоответствие стандарту как-раз можно увидеть на картинке: минуты и секунды подкрашены чёрным цветом, а текст ДО них — синим. Всё дело в том, что первое двоеточие заставляет парсер воспринимать строку, как элемент Ключ: Значение. Дело исправляется обёрткой вывода в кавычки, но опять же — в целях быстрого отладочного вывода это совершенно не критично.

Итак, мы без лишних библиотек, обработок, компонент и прочих велосипедов, парочкой дополнительных пробелов и чёрточек можем существенно облегчить себе восприятие выводимой информации.

Кстати, для любителей библиотек могу привести набросанный на скорую руку код:

Перем мУровень;

Функция Уровень() Экспорт
Возврат мУровень;
КонецФункции

Функция Отступ(Дельта = 0)

Р = "";

Для Инд = 1 По мУровень + Дельта Цикл
Р = Р + "  ";
КонецЦикла;

Возврат Р;

КонецФункции

Процедура ОткрытьРаздел(ИмяРаздела) Экспорт

Сообщить("" + Отступ() + "- " + ИмяРаздела);
мУровень = мУровень + 1;

КонецПроцедуры

Процедура СообщитьСОтступом(Сообщение, Дельта = 0)
Сообщить("" + Отступ(Дельта) + Сообщение);
КонецПроцедуры

Процедура Вывести(Значение) Экспорт

Если ТипЗнч(Значение) = Тип("Массив") Тогда

ОткрытьРаздел("");

Для Каждого мЗначение Из Значение Цикл
СообщитьСОтступом("- " + мЗначение, 1);
КонецЦикла;

ЗакрытьРаздел();

ИначеЕсли ТипЗнч(Значение) = Тип("Структура") Тогда

ОткрытьРаздел("");

Для Каждого мКлючЗначение Из Значение Цикл
СообщитьСОтступом("- " + мКлючЗначение.Ключ + ": " + мКлючЗначение.Значение, 1);
КонецЦикла;

ЗакрытьРаздел();

Иначе
СообщитьСОтступом("- " + Значение);
КонецЕсли;

КонецПроцедуры

Процедура ЗакрытьРаздел() Экспорт

Если мУровень > 0 Тогда
мУровень = мУровень - 1;
КонецЕсли;

КонецПроцедуры

мУровень = 0;

И пример использования:

Перем МаксимальныйУровеньВложенности;

Функция ОпределитьНекотороеЗначение()
Г = Новый ГенераторСлучайныхЧисел;
Ч = Г.СлучайноеЧисло(0, 3);

Если Ч = 0 Тогда

М = Новый Массив;
КоличествоЭлементов = Г.СлучайноеЧисло(1, 5);

Для Инд = 1 По КоличествоЭлементов Цикл
М.Добавить(Г.СлучайноеЧисло(0, 20) - 10);
КонецЦикла;

Возврат М;

ИначеЕсли Ч = 1 Тогда

Возврат Новый Структура("СлучайноеЧисло,ТекущаяДата", Г.СлучайноеЧисло(0, 10), ТекущаяДата());

ИначеЕсли Ч = 2 Тогда

Возврат Г.СлучайноеЧисло(0, 20) - 10;

ИначеЕсли Ч = 3 Тогда

Возврат "СтрокаСтрокаСтрока";

КонецЕсли;

КонецФункции

Процедура Протестировать(Уровень, СлучайныйПараметр = Неопределено) Экспорт

мТекущееЗначениеОтладки = ОпределитьНекотороеЗначение();
ОткрытьРаздел("Вызов ");

ОткрытьРаздел("Параметры вызова");
Вывести("Уровень: " + Уровень);
Вывести("Параметр1: " + СлучайныйПараметр);
ЗакрытьРаздел();

Вывести(мТекущееЗначениеОтладки);

Если Уровень < МаксимальныйУровеньВложенности Тогда

Г = Новый ГенераторСлучайныхЧисел;
Ч = Г.СлучайноеЧисло(0, 10);

Для Инд = 1 По Ч Цикл
ОбработкаПрерыванияПользователя();
Протестировать(Уровень + 1, Г.СлучайноеЧисло(0, 10));
КонецЦикла;

КонецЕсли;

ЗакрытьРаздел();

КонецПроцедуры


Процедура КнопкаВыполнитьНажатие(Кнопка)

МаксимальныйУровеньВложенности = 5;
Протестировать(1);

КонецПроцедуры

Вот пример возможного результата работы:

npp_yaml-lib_example_output

 

Для тех, кому не жалко инфобаксов — обработка приложена.

 

В заключение и немного продолжая тему YAML:

Если вместо Сообщить использовать вывод в файл, то полученную информацию можно будет использовать даже после аварийного завершения программы. Для многих языков программирования существуют парсеры YAML (для 1С: //infostart.ru/public/173076/), что даёт возможность автоматически обрабатывать полученный файл отладочной информации: понять, что было проделано и на каком месте, собственно, рухнуло.

Обработка с выводом в файл в приложении YML-file.epf. Хотя, разница там только в том, что вместо Сообщить используется ЗаписьТекста.ЗаписатьСтроку. Запускаем обработку, обрубаем процесс через диспетчер задач, открываем файл в Notepad++ и видим, что он без проблем парсится.

На этом всё. Благодарю за внимание.

4 Comments

  1. DoctorRoza

    Подход не совсем стандартный, однако он будет применим только программистом. Никакой начальник, тем более юэер, ничего копипастись в нод не будет! 🙂

    Reply
  2. baton_pk

    (1) DoctorRoza,

    юзеры всякие бывают 🙂 наши вот даже в консоли отчётов маньячат.

    Reply
  3. gaglo

    …. я только что узнал, что выводил свои сообщения прозой YAML-ом!…

    Reply
  4. galinka1c8

    Не знаю как начальнику, но себе для отладки пригодится.

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *