Исправление ошибки в Emacs Lisp


9

Мне нужно вызвать функцию и выполнить очистку только в случае сбоя функции, а затем повторно запустить ошибку. Вот псевдокод:

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

Ответы:


10

Кстати, альтернативный вариант может быть что-то вроде:

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

Преимущество состоит в том, что вы избегаете перехвата и повторного выброса ошибки, что означает, например, что отладчик покажет вам правильную обратную трассировку (ту, которая соответствует фактическому источнику ошибки, а не ту, которая соответствует повторной выдаче чужой ошибки). ).

Другое отличие состоит в том, что cleanupон будет вызван не только при ошибке, но также и в том случае, если код прерывается C-gвызовом или throw.


1
Спасибо. Почему бы не condition-caseпоймать keyboard-quit?
Елена

3
Потому что это не ошибка (т. Е. Его сигнал, quitне имеет errorсреди своих родителей). IOW вы также поймать его, condition-caseно для этого нужно положить quitвместе error. Конечно, это все равно не справится с делом `throw '.
Стефан

13

Вы ищете signal:

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

Я считал signal, но его прототип есть (signal ERROR-SYMBOL DATA), нет (signal ERROR).
Елена

@Elena: огорчился, вы должны вытащить его на части с carи cdr. Ответ обновлен.
npostavs
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.