Ponowne przeglądanie błędu w Emacsie Lispie


9

Muszę wywołać funkcję i wykonać czyszczenie tylko wtedy, gdy funkcja się nie powiedzie, a następnie ponownie uruchomić błąd. Oto pseudo-kod:

(condition-case err
    (call-function)
  (error
   (cleanup)
   ;; how do I raise `err`?
   ))

Odpowiedzi:


10

BTW, alternatywną opcją może być coś takiego:

(let ((error t))
  (unwind-protect
      (prog1 (call-function)
        (setq error nil))
    (when error (cleanup))))

Zaletą jest to, że unikasz wychwytywania i ponownego zgłaszania błędu, co oznacza na przykład, że debugger pokaże ci właściwy ślad wsteczny (ten, który odpowiada faktycznemu źródłu błędu, a nie ten, który odpowiada, że ​​ponownie rzucasz błąd innej osoby ).

Inną różnicą jest to, że cleanupzostanie wywołany nie tylko w przypadku błędu, ale także, jeśli kod zostanie przerwany przez a C-glub wywołanie do throw.


1
Dzięki. Dlaczego nie condition-casezłapać keyboard-quit?
Elena

3
Ponieważ nie jest to błąd (tj. Jego sygnał, quitnie ma go errorwśród rodziców). IOW ty van również złapać ją condition-case, ale do tego trzeba umieścić quitobok error. Oczywiście nadal nie poradzi sobie ze sprawą „rzucania”.
Stefan

13

Poszukujesz signal:

(condition-case err
    (call-function)
  (error
   (cleanup)
   (signal (car err) (cdr err)))) ; reraise `err'

Zastanawiałem się signal, ale jego prototyp (signal ERROR-SYMBOL DATA)nie (signal ERROR).
Elena

@Elena: właśnie przepraszam, rozdzieliłeś to na cari cdr. Odpowiedź zaktualizowana.
npostavs
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.