2012-02-24 15 views
9

Mam ogólne pytanie dotyczące praktyk kodowania ...Jak śledzić program do debugowania w OCaml?

Podczas debugowania, w pewnym momencie mojego kodu, potrzebuję trochę kodu, aby wydrukować bieżący stan; Kiedy nie debuguję, nie chcę zostawiać kodu, ponieważ przeszkadza to w widoczności innego kodu ...

Trudno jest spakować je w jedną funkcję, ponieważ w większości przypadków zawiera ona zmienne lokalne i nie chcę podawać wszystkiego jako argumentów ...

Jak więc ogólnie zarządzać tego rodzaju "drukowania/sprawdzania" kodu? czy jest jakaś dobra praktyka?

Odpowiedz

5

często używam funkcji debugowania, które drukuje wartość tylko wtedy, gdy flaga debugowania jest ustawiony na true:

let debug_flag = ref false 

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

Chodzi o to, że to, co chcę wydrukować, obejmuje kilka linii i obejmuje wiele zmiennych lokalnych ... – SoftTimur

+1

Problem z tą funkcją debugowania polega na tym, że argumenty są zawsze obliczane, nawet jeśli nie są używane na końcu. –

6

Miałem funkcję debugowania, które drukuje tylko końcowy łańcuch tylko wtedy, gdy flaga była zestaw. Teraz, wolę po prostu dodać if oświadczenia:

  • nie są one znacznie dłużej
  • nic nie jest obliczany jest warunek jest fałszywy
  • łatwo jest podczas czytania kodu, aby zobaczyć, że to jest tylko do debugowania

ja również użyte do makr camlp4, które generują if sprawozdania z aplikacji funkcji, ale działa tylko w projektach, w których wykorzystywany jest camlp4, które staram się unikać w dzisiejszych czasach.

Należy zauważyć, że zazwyczaj nie używam jednej flagi debugowania, ale wiele flag debugowania, po jednym na moduł, a następnie metatagów, które spowodują debugowanie kilku modułów lub aspektów ortogonalnych. Są one umieszczane w hashtable jako lista flag i mogę ustawić je za pomocą argumentu lub zmiennej środowiskowej.

4

używam rozszerzenia składni rejestrowania:

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

Można także przekazać numer linii do funkcji rejestrowania (który jest zakodowany do AuxIO.log w źródle powyżej) używając Loc.start_line _loc (być może będę dodaj to).

Należy zauważyć, że warunkowe powinno być częścią rozszerzenia składni, w ten sposób nie będzie obliczać argumentów, jeśli nie musi ich drukować. Mamy również elastyczną składnię "printf".

Również używam komendy w Emacs:

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

wraz ze składanym `trybie”.