さて、一行電卓がなんとか出来上がりました。でも、やはり式として成り立たない文字列を入れると落っこちるのでは、どこかの三流プログラマがヒイヒイ言いながら作ったみたいでイヤですね。まあ、実際はまったくそのとおりなんですが‥
そこで今回は「エラー処理」を入れてみます。「ちょっと待て」と言いたいあなた。ええわかってます。Perlゆずりの強力な正規表現を使って、スラスラッと入力チェック処理を書けばいいじゃないかと。はいはいそのとおりですね。やってみたけどうまいパターンが書けなかったんですよ。ひんひん僕なんか僕なんか。
ということで、気を取り直してレッツ「エラー処理」です。エラー処理(「例外処理」と言うみたいです)を行うには、対象となる部分を begin/end で囲み、例外が発生した時の処理を rescue 節に書き込めばオッケーです。もちろん他にも色々な機能があるので Ruby の参考書に目を通すことをお勧めしますが、今回はこの最も単純なやり方を使います。
それでは論より証拠、能書きよりソースと先人も言っていることですし、エラー処理を入れたスクリプトを見てみましょう
# CalcCntl
require 'osx/cocoa'
class CalcCntl < OSX::NSObject
ib_outlets :field
def calc (sender = nil) begin # 追加 ans = eval input_value = @field.stringValue.to_s @field.setStringValue (input_value + " = " + ans.to_s) rescue ScriptError, StandardError # 追加 @field.setStringValue ("error") # 追加 end # 追加 end end
これで、間違って変な数式や日本語を入力した場合には、フィールドに "error" と表示されます。また、 @field.setStringValue ("error") の行を削除すると、"error" を表示せずに入力された文字列をそのままさらし者にします。こちらの方が修正もしやすいのでお勧めかもしれませんね。
ところで rescue の後に続く "ScriptError" と "StandardError" ですが、これは Ruby が事前に定義しているエラー階層の中から選びました。参考までに、エラー階層の構成を示しておきます。
Exception
fatal(Rubyが内部的に使用)
Interrupt
NoMemoryError
SignalException
ScriptError
LoadError
NameError
NotlmplementedError
SyntaxError
StandardError
ArgumentError
FloatDomainError
IndexError
IOError
EOFError
LocalJumpError
RegexpError
RuntimeError
SystemCallError
SystemStackError
ThreadError
TypeError
ZeroDivisionError
さてさて、ちょっと頭休めです。今回スクリプトにエラー処理を追加しましたが、実はこれ、スクリプト修正後の再ビルドがいらないんですよ。といってもProjectBuilderで素直に編集した場合は再ビルドが必要ですけどね。
MacOS X ではアプリケーションとして表示されているCocoaアプリが、実際にはパッケージ化されたフォルダだということはご存じだと思います。calc アプリのアイコンを選択して、コンテクストメニューから「パッケージの内容を表示」を選び、calc → Contents → Resources と階層をたどってみてください。最後のウィンドウの中に CalcCntl.rb というファイルがありますね。こいつをエディタで直接修正すれば、再ビルドせずにアプリが実行可能です。
なお、もうひとつ奥の階層にあるNibファイルを直接編集して、インターフェースの変更をした場合も、保存後にすぐ変更が反映されます。
では、最初に実行したビルドは無駄なのでしょうか。ここらへんを詳しく説明しようとするとややこしくなりますが、要はアプリ実行用の土台を作るために必要なんだと考えてください。フォルダをアプリとしてパッケージ化するためには、Appleの指定した方法で、指定した場所に正しくファイルを配置する必要があります。ビルドとは、この作業をProjectBuilderにおまかせしようということです。特にRubyスクリプトとNibファイルは、プロジェクト用のフォルダから指定のフォルダにコピーされているだけですので、一旦配置されてしまえば修正は自由にできます。この手軽さがRubyCocoaのアドバンテージのひとつでしょうね。