Ruby側のメソッドからbool値をObj-C側に返したときの挙動がヘン?
iStacで、Ruby側のメソッドからbool値をObjective-C側に返したとき、どうも、if文の判定がうまくいっていないらしいという報告がありました。
具体的には、Ruby側でSSBへの登録を行い結果が正常であれば true を Objective-C側のクラスに返しているんだけど、その戻り値がすべてfalseとして判定されて判定されているらしいということ。Objective-CとRubyCocoaの間の型のひも付けがどのように行われているかも疑問だったので調べてみた。
そしたら、http://limechat.net/rubycocoa/wiki/?Reference#ob6f3cf3に objc_method に関しての記述があった。
どうやら、Objective-Cの世界からRubyCoco側のメソッドを呼び出す場合に、戻り値や引数の型を Objective-C側に教えてあげる必要があるらしい。
この情報を元にサンプルを使って試してみた。
コントローラと、そこから呼び出されるObjective-Cのクラスを作った。
(追記:2008.10.18) 追加ポイントはココ↓
# Objective-C側から呼び出してもらうコールバックメソッド objc_method :callback, [:BOOL, :BOOL] def callback(para)
元々rubyのメソッドのシグネチャには引数や戻り値の「型」に関する情報をもっていないが、objc_methodによってcallbackメソッドのシグネチャObjective-Cから解釈できるように宣言してあげている。これでObjective-C側で正しい値として受け取れるはず...
で、実行結果がこれ
doTest: 2008-10-16 00:44:46.235 test[3744] *** Call from RubyCocoa > param: 0 callback: para is 0 callback return <false> 2008-10-16 00:44:46.235 test[3744] *** callback returned [0] 2008-10-16 00:44:46.235 test[3744] *** callback returned <FALSE>
どうやら、うまくいったみたい。
最初、BOOLじゃなくて小文字のbool(C++のbool?)を使っていたんだけど、それだとうまく行かなかった。最初の数回の呼び出し時になぜか1を返していて、3回目の呼び出しぐらいから正しく0を返してくる意味不明な動作していた... とりあえずは、RubyCocoa使うときに真偽値の受け渡しする場合は bool ではなく BOOL を使った方がよさそう。
もしかしたら、実行環境によって戻り値が不定なのは、この辺が関係してるかもしれない。
※相変わらず Objective-Cが良く分かってないので、Objective-C本を買うことにした。あとCocoa本として評価の高いヒレガス本もあわせて...そのついで(?)に Leopardも注文してしまった。今度の週末が楽しみ。
この調子じゃまた外に出れないなぁ。