gaucheによるUNIXコマンドプログラミング〜catコマンド・例外(エラー)処理編〜


 何らかのエラーが起こった場合(例外が投げられた場合)の処理を加えてみました。以下がソース。

#!/usr/bin/gosh

(define (main args)

  (if (null? (cdr args))
	  (copy-port (current-input-port) (current-output-port))
     ; start guard phase
	  (guard (ex
		          ; catch phese (if vb)
       ; start exception process
			  ((<error> ex) (print ex))		; if catche <error> condition
			  (else (print "Usage: gshcat [OPTION] [FILE]")))		; otherwise
                          ; end exception process

	   ; main process
		(for-each
		 (lambda (file)
		   (call-with-input-file file (lambda (in) (copy-port in (current-output-port)))))
		 (cdr args))))

  0)


 gaucheにおいての例外処理、VBなどにおける「try〜catch構文」は、「guard構文」を使って実現します。公式ドキュメントには、

Macro: guard (var clause …) body …

Gauche Users’ Reference: Top

として定義されています(マクロなのか…)。上記のソースでは、変数部に「ex」を、例外の種類に応じての処理を「clause」部に書いています。今回は簡単に、「指定されたファイルが存在しなければ、「no such file or directory」と表示する」という感じにしようと思いました。しかし、ファイルの読み込みエラーの時には、「io-read-error」コンディション(コンディションは、他の言語でいう、例外オブジェクト)が投げられるかと思いきや、その親クラスの「error」コンディションが投げられていて、ファイルの読み込み時のエラーが特定できませんでした。コンディションの構成は以下の通り。



+-
+-
| +- ; also inherits
+-
+- ; also inherits
+-
+-
+-
+-
+-
+-
+-
+-
+-

Gauche Users’ Reference: Top

よって、ここではコンディションそのもののメッセージを表示するようにしました。


投げられたコンディションが、何のコンディションなのかという情報は、どうやって取得すればよいのだろうか…


これらの簡単な例外処理を加えてみて、

  • 自前のコンディションを作成して、例外を投げる
  • 投げられた例外に応じて、表示するメッセージを変化させる

などをさらに加えれば、より柔軟なツールにすることができそうな気がします。


長くなってしまったので、オプション処理は次回に。