RubyCocoa プログラミングでバグを減らすアイディア
MiniKidsGames の Tat さんとのコメントのやりとりで思いついたのだけれど、「nil が来ないことを期待されているところで nil を渡されてしまうことによるクラッシュ」を減らすためのちょっとしたアイディアが浮かんだ。
通常、Cocoa のメソッドでパラメータに nil を渡してはいけないものに nil 渡すと NSInvalidArgumentError が発生する。なので、それでわかるのだけれど、ここでハマリがちなのが、Array -> NSArray や Hash -> NSDictionary への自動変換だ。ちょっと試してみると
% irb -r osx/cocoa irb> ary = [1, nil, 3] => [1, nil, 3] irb> nsary = OSX::NSArray.arrayWithArray(ary) 2006-12-09 07:43:40.565 irb[13501] *** Uncaught exception: <NSInvalidArgumentExc eption> *** -[NSCFArray addObject:]: attempt to insert nil zsh: trace trap irb -r osx/cocoa
とまあこうなったりする。これはどこが問題かわかりにくいので、変換時 (framework/src/objc/ocdata_conv.m の中の処理) で明示的に例外を出すようにしたほうがいいんじゃないかと思うのだ。これで、配列にいれた要素が予期せず nil になっているときは Cocoa 側には渡せないってことになる。
悩むのは NSDictionary ではキー、値とも nil は禁止なのだけど、値には NSNull が利用できるってところだな。nil のとき、これを NSNull で置き換えてよいかなあ。
(以下 2006.12.09 追記)
[rubycocoa-devel:481] で提案とパッチ。個人的な見解としては例外にすること自体は全然問題はなくって、あとは例外のクラスが ArgumentError でいいかどうかってあたりが議論したいとこ。この例外が発生するのは、Ruby から Objective-C 側に渡すときだけだから ArgumentError であるってのはそんなにおかしくはないと思うのだけれど、もっと適したものがあるかもしれない。
今回の実装では、ハッシュの値は NSNull に変換するようにした。これでなにか問題になるようなら、-w や -d でメッセージを冗長にしたとき NSNull への変換に関するメッセージを出力するようにすればいいかなと考えている。
| 固定リンク
最近のコメント