Комплексный контроль за качеством кода
Страница 3. Номера строк или уникальные метки?


 

3. Номера строк или уникальные метки?

В большинстве систем разработки, в сообщении, выводимом при активизации процедуры Assert, выводится три параметра: сообщение пользователя, имя исходного модуля и номер строки, в котором находился вызов процедуры. При этом основной упор при поиске ошибки делается на номер строки и имя модуля, а сообщение пользователя является малоинформативным. Однако, если вы решили оставить вызовы процедуры Assert в готовой распространяемой программе, здесь таится проблема. При разработке программы вы будете выпускать десятки и десятки версий, и естественно, что исходный код будет сильно модифицироваться, а номера линий, на которых располагаются проверочные вызовы, будут постоянно изменяться. И если вдруг ваш пользователь сообщает о том, что в вашей программе сработала проверка на линии N в исходном модуле M, вы должны задаться вопросом, какая версия программы находится у пользователя? Даже если вы сохраните все исходные тексты абсолютно всех версий, такой подход нельзя назвать удобным и ясным, он таит в себе скрытую путаницу и неразбериху, поскольку вам придется отслеживать номера строк в разных версиях программы при просмотре развития программы.

Возникает идея - совсем отказаться от номеров строк - они таят в себе хаос, и использовать уникальные сообщения пользователя, то есть уникальные метки. В каждом вызове процедуры Assert передавать абсолютно уникальный, не повторяющийся идентификатор, и выводить его на экран при срабатывании проверки. После того как вам сообщат, что вашей программе активизировалась проверка с идентификатором N, вы можете проследить развитие кода в этом месте во всех версиях программы путем простого поиска идентификатора в исходных текстах. Зачастую даже, вовсе не обязательно распаковывать ту же версию исходных текстов программы, что и версия программы у пользователя. Если код в этом месте давно не менялся, вы можете искать и исправлять ошибку прямо в текущей версии исходных текстов.

Что выбрать в качестве уникальных идентификаторов? Можно выбрать любое не повторяющееся число или строку. Например, последовательно передавать числа от нуля и далее с инкрементом на единицу. Или передавать уникальные строки, которые можно придумывать на ходу. Однако, это утомительное занятие - помнить последний набранный номер или строку и не повторяться. Можно написать специальный модуль для редактора в среде Delphi, который будет автоматически вводить идентификаторы. Однако, если вы будете работать над проектом на разных машинах, то возникнет проблема синхронизации счетчиков.

Существует прекрасный вариант решения этой проблемы. В среде Delphi нажмите клавиши <CTRL>+<SHIFT>+<G> и вы получите строку похожую на эту: ['{19619100-22B0-11D4-ACD0-009027350D25}']. Это уникальный идентификатор GUID (Global Unique IDentificator), шестнадцатибайтное уникальное значение, переведенное в строковый вид с разграничителями и заключенное в квадратные скобки. Такое значение уникально, оно зависит от времени и от номера сетевой карты. Если сетевой карты нет, то номер генерируется программно. По крайней мере, Microsoft утверждает, что такой номер никогда не повторится. Каждый раз, когда вы нажмете соответствующую комбинацию клавиш, система сгенерирует новый уникальный код. Если удалить квадратные скобки по бокам, то получиться отличный уникальный строковый идентификатор, готовый к использованию, при этом вызов процедуры AssertMsg будет выглядеть подобным образом. 

AssertMsg(FCount > 0, '{19619100-22B0-11D4-ACD0-009027350D25}'); 

В данном случае сообщение пользователя не передается - передается только уникальная метка. В самом деле, какая разница пользователю, отчего именно погибла ваша программа? Пользователь лишь должен сообщить, что ваша программа работает с ошибкой и передать информацию, которая поможет эту ошибку найти. Конечно, подобный уникальный номер занимает некоторое место в сегменте констант, но, как показывает практика, не больше 5% от всего объема программы, и в добавление, такой номер очень удобно записывать с экрана. Кроме того, он действительно никогда не повторяется! Если же вы - эконом, и вам жалко тратить 38 байт на каждый идентификатор, можете передавать в процедуру AssertMsg четырехбайтное число, которое можно получить, взяв первые восемь шестнадцатеричных цифр из строкового идентификатора - именно они изменяются чаще всего. 

AssertMsg(FCount > 0, $19619100); 

 
« Предыдущая статья   Следующая статья »