Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to trace a program for debugging in OCaml ?

I have a general question regarding coding practices...

While debugging, at some point of my code, I need some code to print the current state; When I don't debug, I don't want to leave the code there because it bothers visibility of other code...

It is hard to package them into one function because most of the time, it involves local variables, and I don't want to pass everything as arguments...

So how do you generally manage this kind of "printing/checking" code? is there any good practice?

like image 465
SoftTimur Avatar asked Feb 24 '12 06:02

SoftTimur


3 Answers

I used to have a debug function, that would only print the final string only if a flag was set. Now, I prefer to just add if statements:

  • they are not much longer
  • nothing is computed is the condition is false
  • it is easy while reading the code to see that it is only for debugging

I also used to have camlp4 macros, that would generate if statements from function applications, but it only works in projects where camlp4 is used, which I tend to avoid nowadays.

Note that, usually, I use not one debug flag, but many debug flags, one per module, and then meta-tags that will trigger debugging of several modules or orthogonal aspects. They are put in a hashtable as list of flags, and I can set them with either an argument or an environment variable.

like image 63
Fabrice Le Fessant Avatar answered Nov 09 '22 11:11

Fabrice Le Fessant


I often use a debug function which prints value only when a debug flag is set to true:

let debug_flag = ref false

let debug fmt = 
  if !debug_flag then Printf.eprintf fmt 
  else Printf.ifprintf stderr fmt
like image 23
Çağdaş Bozman Avatar answered Nov 09 '22 12:11

Çağdaş Bozman


I use a logging syntax extension:

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

You can also pass line number to the logging function (which is hard-coded to AuxIO.log in the source above) using Loc.start_line _loc (perhaps I'll add it).

Note that the conditional should be part of the syntax extension, this way it will not compute the arguments if it does not need to print them. Also, we have the flexible "printf" syntax.

Also, I use a command in Emacs:

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

together with `folding-mode'.

like image 4
lukstafi Avatar answered Nov 09 '22 13:11

lukstafi