実践Common lispを読み始めた-第19章 例外処理を超えて:コンディションと再起動(1)
handler-caseとhandler-bind
try{ hogehoge... }catch(Exception e){ yogeyoge... }
が
(handler-case (hogehoge ...) (exception (e) (yogeyoge ...)))
に相当する。
一方のhandler-bindは特定の例外処理を決めるのだけど、処理した後さらに上位のハンドラに通知する。
(handler-bind ((exception (e) #'yogeyoge) ...) (hogehoge ...))
は
try{ hogehoge ... }catch(Exception e){ yogeyoge ... throw e; }
と同じか?(自信なし)
実際に動くコードを書いてみる。
CL-USER> (define-condition invalid-argument-exception (error) ((message :initarg :message :reader message) (value :initarg :value :reader value))) INVALID-ARGUMENT-EXCEPTION CL-USER> (defun level1 (arg) (handler-case (level2 arg) (invalid-argument-exception (err) (format t "Invalid argument in level2")))) LEVEL1 CL-USER> (defun level2 (arg) (handler-bind ((invalid-argument-exception #'(lambda (err) (format t "level2: InvalidArgumentException: ~a~%" (value err))))) (level3 arg))) LEVEL2 CL-USER> (defun level3 (arg) (error 'invalid-argument-exception :message "InvalidArgumentException" :value arg)) ;;level3は必ずエラーを投げる LEVEL3 CL-USER> (level3 10) ; Evaluation aborted ;;予定通り CL-USER> (level2 10) level2: InvalidArgumentException: 10 ; Evaluation aborted ;;handler-bindだけなので、例外処理された後toplevelに例外が投げられてデバッガに制御が移る。 CL-USER> (level1 10) level2: InvalidArgumentException: 10 Invalid argument in level2 NIL ;;level1ではhandler-caseを書いているのでデバッガに制御はいかない。 CL-USER>
handler-caseとhandler-bindだけだと他の言語の例外とそれほど差がないなー。