開発者はコードを書くのを楽しむものだが、例外処理コードを書くのを楽しんでいる開発者はほとんどいないし、それを正しくやれる人はもっといない。Avdi Grimm氏の書いた本、Exceptional Rubyはこの課題に挑み、信頼できる例外処理コードに開発者が正しく取り組むための手助けをする。
Exceptional Rubyは例外とエラー処理に対する新たな指針だ。内容は100ページを超え、動かせるサンプルがつまっている。また、アプリケーションのエラーに合わせて、例外がどのように機能するのか詳しく解説する。
InfoQでは、この本と例外処理について、著者であるAvdi Grimm氏に話を聞いた。
最近のプログラミングやフレームワークに関する本では、複雑な詳細について解説しないものが多い。この本がほかの多くの本とどう違うのか、Avdi氏は次のように説明した。
Exceptional RubyはRubyにおける例外処理テクニックについての本です。ほかの本は例外とエラー処理に1章か2章ほどしか費やしていませんが、Exceptional Rubyではそれに100ページ以上を費やしています。例外がどのように機能するのか、状況に合わせてどのようにRubyの例外システムをカスタマイズするのか、例外の代替案、コードが例外セーフであることをどのように検証するか、クリーンでロバストなエラー管理アーキテクチャをどのように構築するか、詳しく説明しました。
開発者は早々に例外について知るのだが、例外をうまく利用するためには深い理解が必要になる。この本は多少経験のある開発者向けだ。
私は上級Rubyプログラマのためにこの本を書きました。Rubyの基礎がわかっている人なら本書から得られるものがあるでしょう。ベテランRubyistであれば、新しい技が学べるでしょう。あなたがMatzでない限り、Rubyやエラー処理について学べることがあるはずです。
Rubyの例外処理といった1つのテーマにこれだけの分量を割くなんて、一体この本からどんなことが学べるのだろうか。
まず、Rubyの例外システムがどのように機能しているのか、深くて実践的な理解が得られるはずです。そして、よりよいプログラムを書くために、その知識を活用できるはずです。例外的な状況を処理するための道具が手に入るのです。どんな場合に例外を発生させるとまずいか、呼び出し元が提供するコールバックなど、例外の代わりにどうするのが望ましいか、といったことがわかるようになるでしょう。
エラー状態から復旧できるようにするための、エラーの連鎖反応を回避するための、実績あるパターンが学べるでしょう。「例外の安全性」という考え方を理解して、非常にクリティカルなメソッドが予期せぬ例外に直面してもロバストであることを検証する方法について学べるでしょう。後付けではなく、エラーを十分認識したアプリケーションやライブラリの書き方がもっと深く理解できるでしょう。
一般的に、プログラムにおける例外処理というのは、いろいろな人によって後付けされるものであり、必ずしもベストプラクティスを頭に置いてやられるものではない。Avdi氏は、ほかの開発者がとってきた例外処理のアプローチについて、次のように述べた。
エラーをどう扱えばよいのか指針がないことに、開発者らは悩まされていると思います。私がこの本(またそれに先立つお話)を書いた理由のひとつは、自分のプロジェクトで問題をもっとうまく処理する必要があると感じたためでした。例えば、例外クラス階層をどう組み立てるのがよいか、といった疑問にどれだけ苦しんできたことか、言葉では言い表せません。こうした領域には信頼できる指針がありませんでした。非常にすぐれたプログラミング本ですら、エラーに関する章にページが割かれていることはめったにありません。
しかも、Rubyコミュニティにはこの分野における古典と言えるものがなく、苦しんできました。例えば、私が説明した例外の安全性テストテクニックは、もう何年も前にC++コミュニティで出会ったものです。実際のところ、Rubyを使うともっと簡単にできるのですが、これについて書かれたRuby本や記事を目にしたことはありません。
一番よく見かけるのは、単にエラーケースを後付けで足していくことですね。稼働中に期待しない例外が不意に起こると、それを何の疑いもなくbegin/rescue/endブロックで塞いでしまうような、ぐちゃぐちゃなコードをよく見かけます。
また、Rubyでは、例外は文字通り「どこでも」起こり得るのだということをきちんと考慮していないコードをよく見かけます。これは例外の安全性とメソッドが例外セーフであることを検証するためのセクションを入れた理由のひとつです。
たくさんのAPIがいたずらに例外を発生します。メソッドが例外を発生するとき、そのメソッドは「私はこのイベントが期待されていないことを事実として知っている」と表明しています。しかし、あるプログラマにとって「期待されない」ことも、別のプログラマにとっては日常茶飯事であることがあります。うってつけの例は、HTTPライブラリです。これは「404 Not Found」という例外を発生します。クライアントのコードがありきたりのイベントを処理するのに "rescue" ブロックでAPI呼び出しをラップしなくてはならないのなら、そのAPI設計には何かが欠けているということです。たいていの場合、何が本当に例外的なケースかの判断をクライアントコードに委ねることで、APIを改善することができます。
最後に、黙って無視されるようなエラーを引き起こす、大きすぎる "rescue" 節があることで発生する厄介なバグをたくさん見てきました。本書ではかなり時間をかけて、キャッチしたいものを特定するよう、"rescue" 節を厳重にするテクニックについて説明しています。これはサードパーティライブラリが汎用型の例外を発生させるときにも使えます。
1つのソフトウェア開発トピックについて深い知識を得るためには経験が必要だ。そして、エラー処理といった人気のないトピックに確かな知識を得るためには規律が必要だ。こうした知識はどうやって手に入れたのだろうか?
私はもう10年にわたり、Rubyを使って仕事をしてきました。そのため、多くは個人的な経験に基づいています。私はかなりの時間をかけて、取り組んできたプロジェクトで見てきた、共通のパターンおよびアンチパターンをふりかえりました。また、ほかのベテランRubyistから、Rubyの例外について思っていることを収集しました。例えば、Jim Weirich氏から学んだ、"raise" と "fail" という同義語のどちらを選ぶべきかといったルールを取り入れました。
また、本書が確立されたプログラミング文献に基づいているよう強く望みました。そこで、"Code Complete"、"The Practice of Programming"、"The Pragmatic Programmer"といった古典を本棚から引っ張り出して、エラー処理に関するセクションを読み返しました。それらの定義や、例外やエラーについて検討するための信頼できるフレームワークを確立するために、Bertrand Meyer氏の "Object-Oriented Software Construction" に立ち返りました。Meyer氏のプログラミング言語Eiffelは、Rubyの例外システムに強い影響を与えています。メソッドが呼び出し元と「契約」を共有するというアイデアは、「エラー」「失敗」「例外」といった用語について語るとき、何を意味しているかを明確にするのに本当に役立ちます。
開発者はベストプラクティスを学ぶことを望んでいる。Exceptional Rubyで解説されているトピックは、ベストプラクティスと言えるのか、それとも、開発者自身が実践困難な曖昧なメソッドなのか。
Rubyにおいて確立された実績のあるパターンやイディオムの実装方法を示すこと、そして、多くの読者にあまり知られていないテクニックを紹介すること、これらをうまく両立させようと試みました。そのため、Steve McConnell氏によって書かれ、(最近では)Michael Nygard氏が実演したBulkheadパターンのようなものも本書には含まれています。また、名前空間の例外に対して、Tag Modulesを使うテクニックなども含まれています。
Avdi Grimm氏はRubyコードを10年間もハックしており、今なおRubyを愛している。数多くのRubyカンファレンスやユーザグループで講演し、彼のブログ Virtuous Code では、(特に)Rubyに関するヒント、指針、スタイルを書いている。持続可能なソフトウェア開発と地理的に分散したアジャイルチームのファシリテートを専門とするコンサルタント会社、ShipRiseのチーフエアロノート。ペンシルバニア州のヨーク郡に、妻と4人の子供とともに暮らしている。
Exceptional Rubyについて、詳しくはこの本のWebサイトを参照。InfoQの読者はディスカウントコード INFOQER を使って $3オフで購入できる。
Avdi氏は2011年5月17日-19日にメリーランド州ボルチモアで開かれるRailsConfで講演する予定だ。彼に会いたければ参加するとよいだろう。