Help us understand the problem. What is going on with this article?

zsh で 例外処理

More than 5 years have passed since last update.

zsh はプログラム言語で言うところの try/catch のような例外処理ができるので紹介する。

シンプルな例

書き方はこんな感じ。

#!/bin/zsh

autoload -Uz catch
autoload -Uz throw

{
  echo hoge
  throw 'MyException'
  echo fuga
} always {
  if catch 'MyException'; then
    echo "catch MyException!"
  fi
}

例外を投げるには throw、受け取るには catch という関数を使う。まずは両方とも autoload しておく。

例外処理をするときは全体を

{
  # try ブロック
  # ここにメイン処理を書く
} always {
  # always ブロック
  # 例外が発生した時もそうでない時も実行される
}

という形で書く。
always ブロックは例外が発生したかどうかにかかわらず常に実行されるので、この中で catch を使って例外が発生したかどうか判定すれば例外をキャッチできる。

この例を実行した結果はこんな感じ。

% ./exception_sample.zsh
hoge
catch MyException!

例外を投げた時点でうまく always ブロックに移行してるのが分かる。

複数の例外の種類を考慮する例

もうちょっと複雑な例を見てみる。

#!/bin/zsh

autoload -Uz catch
autoload -Uz throw

{
  lock_dir_name="lock_dir"

  mkdir $lock_dir_name || throw 'LockException'

  # メイン処理
  # ...

  rmdir "$lock_dir_name"
} always {
  if catch '*'; then
    case $CAUGHT in
      (LockException)
        echo "LockException"
        ;;
      (NetworkException)
        echo "NetworkException"
        ;;
      (*)
        echo "other Exception"
        ;;
    esac
  fi

  # 後処理が必要ならここに書く
  # 例外が発生するかどうかにかかわらず実行される
  # 他の言語で言う finally に相当する

  echo "tear down"
}

このスクリプトでは、ディレクトリを作って排他制御をしてる。ロックの取得に失敗したときはすぐに例外を投げてメイン処理を行わないようになってる。

この例のように catch の引数はワイルドカードが使えるので、catch '*' とすればどんな名前の例外でもキャッチできる。どんな例外もキャッチして、例外の種類ごとに違うことをしたい場合はこんなふうに書くとうまくいく。

その他詳しいことは man zshcontrib の EXCEPTION HANDLING や man zshmisc の COMPLEX COMMANDS の { try-list } always { always-list } を参照。

こんな感じで例外処理を使うとエラー処理がシンプルに書けるようになるので、ぜひ試してみてください!

mollifier
zsh, vim, vimperator, JavaScript, iOS, .NET に興味があるプログラマ
http://mollifier.hatenablog.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした