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

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

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

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

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

Ответ 1

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

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

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

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

Ответ 2

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

let debug_flag = ref false

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

Ответ 3

Я использую расширение синтаксиса ведения журнала:

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)))

вместе с `folding-mode '.