Как отследить программу для отладки в OCaml?

У меня есть общий вопрос относительно практики кодирования...

Во время отладки в какой-то момент моего кода мне нужен код для печати текущего состояния; Когда я не отлаживаю, я не хочу оставлять код там, потому что это мешает видимости другого кода...

Трудно объединить их в одну функцию, потому что большую часть времени она включает локальные переменные, и я не хочу передавать все в качестве аргументов...

Итак, как вы вообще управляете этим видом "печати / проверки" кода? есть ли хорошая практика?

3 ответа

Раньше у меня была функция отладки, которая выводила бы финальную строку, только если был установлен флаг. Теперь я предпочитаю просто добавить if заявления:

  • они не намного дольше
  • ничего не вычисляется, если условие ложно
  • при чтении кода легко увидеть, что он предназначен только для отладки

У меня также были макросы camlp4, которые генерировали бы if операторы из функциональных приложений, но это работает только в проектах, где используется camlp4, чего я стараюсь избегать в настоящее время.

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

Я часто использую функцию отладки, которая печатает значение только тогда, когда для флага отладки установлено значение true:

let debug_flag = ref false

let debug fmt = 
  if !debug_flag then Printf.eprintf fmt 
  else Printf.ifprintf stderr fmt

Я использую расширение синтаксиса регистрации:

http://toss.svn.sourceforge.net/viewvc/toss/trunk/Toss/caml_extensions/pa_log.ml?revision=1679&view=markup

Вы также можете передать номер строки в функцию регистрации (которая жестко AuxIO.log в приведенном выше источнике) с помощью Loc.start_line _loc (возможно, я добавлю это).

Обратите внимание, что условное выражение должно быть частью расширения синтаксиса, поэтому оно не будет вычислять аргументы, если ему не нужно их печатать. Кроме того, у нас есть гибкий синтаксис "printf".

Также я использую команду в Emacs:

(defun camldev-insert-log-entry ()
  (interactive)
  (insert "(* {{{ log entry *)
LOG 2 \"\";
(* }}} *)")
  (goto-char (- (point) 12)))

вместе с "режимом складывания".

Другие вопросы по тегам