2014-04-07 18 views
8

Uważam, że rozwój przyrostowy ma tendencję do zerwania podczas kodowania Hunchentoot.Uzyskiwanie dostępu do obiektów żądania Hunchentoot z REPL do debugowania

Na przykład mogę napisać stronę internetową, która składa się z kilku funkcji. Jeśli jedna z tych funkcji wewnętrznych zawiera wywołanie funkcji - powiedzmy - hunchentoot: post-parameters *, wówczas nie mogę łatwo przetestować funkcji w REPL. To spowoduje błąd, ponieważ * request * nie istnieje, chyba że strona jest wywoływana przez klienta WWW.

Byłoby miło, gdyby niektóre funkcja-lub-inne-source istniał taki, że mogę przetestować-funkcję w następujący sposób:

>(let* ((*request* (get-previous-request-from-somewhere)) 
     (*session* (slot-value *request* 'hunchentoot:session))) 
    (my-function <whatever params>)) 

Czy to lub coś podobnego istnieje? Czy mam lepsze podejście do debugowania?

+0

Wygląda na to, że wystarczy utworzyć urządzenie, które zwróci próbne żądanie. To nie powinno być trudne. Na przykład zobacz: https://github.com/russell/planet-git/blob/master/t/traverser.lisp#L55-L63 fiveam ma osprzęt, jeśli jesteś tak pochylony – PuercoPop

Odpowiedz

6

Moje rozwiązanie tymczasowe wygląda mniej więcej tak:

(defparameter *save-last-request* t) 
(defvar *last-request* nil) 

(defun store-request() 
    (when *save-last-request* 
    (setf *last-request* *request*))) 

(defmacro with-last-request (&body body) 
    `(let* ((*request* *last-request*) 
     (*session* (slot-value *request* 'hunchentoot:session))) 
    ,@body)) 

współpracuje z zastrzeżeniem, że każda procedura obsługi musi wykonać połączenie do store-request.

+0

Ponieważ jest to co najmniej pół kludge (ponieważ żądanie sklepu musi być wywoływane jawnie), mam wątpliwości co do przyznania całej nagrody - jeśli ktoś byłby tak uprzejmy, by dać jeszcze +1, połowa nagrody byłaby przyznawana automatycznie - więc proszę zagłosuj: -) –

1

Myślę, że najprostszą rzeczą do zrobienia może być użycie niestandardowej klasy żądania, która wprowadza sposób, aby utrzymywać żądania gdzieś w łańcuchu inicjalizacyjnym.

Oto trywialny przykład jednego podejścia. Niestandardowa podklasa żądania, które zapisuje stan w globalnym stosie.

Można ustawić akceptujące używać niestandardowych żądań klas używając

(setf (acceptor-request-class acceptor) new-value)

więc coś w tym

(defparameter *requests* nil) 
(defclass my-request (hunchentoot:request)()) 
(defmethod initialize-instance :after ((req my-request) &key) 
    (push req *requests*)) 

a następnie ustawić klasy prośba akceptor używać tego podczas dokonywania akceptor np

(setf (hunchentoot:acceptor-request-class 
     (make-instance 'hunchentoot:easy-acceptor)) 'my-request) 

każdym razem, gdy żądanie jest stworzone przez tego akceptora przejść do przewodnika, zostanie on dodany do listy *requests*.

jeśli używasz zmiennej do określenia nazwy klasy żądania, możesz włączać i wyłączać tę klasę podczas programowania/debugowania.

Następnie można wziąć wnioski z tego stosu w powiązaniu testowym.