Objective-CのコードをRubyMotionに移植してて引っかかったこといろいろ

| コメント(0) | トラックバック(0)

この記事は RubyMotion Advent Calendar 2012 の 16 日目の記事です。

いきなりRubyMotionで書き始めるのはなかなか辛いので、最初は語彙を増やすたObjective-CのサンプルプログラムをRubyMotionで実装するというのを結構やりました。

Objective-Cのコードをコピペして文法をRubyに書き換えていくのは慣れればそれほど難しくないのですが、最初は簡単なことで次々と引っかかって手が止まることが多かったので覚えている限りですがリストアップしていこうと思います。

形式プロトコルの指定は悩まないで省略してよし

モジュールのincludeとかそういうのかなー?といろいろやったりしましたが、RubyはObjective-Cよりもっと動的な言語なのでメソッドは実行時に存在すればOKという事(たぶん)で次のような形式プロトコルの採用の指定 は無視しても良さそうです。

また非形式プロトコルは既存クラスを開いてメソッドを追加する(オープンクラス)だけです。

オーバーライドして親の実装を呼ぶのはsuperだけでよい

パラメータが必要な場合でもsuperを呼ぶだけで、パラメータもそのまま親クラスのメソッドに渡されます。

型の宣言はすべてばっさり落とす

先ほどの例のメソッドパラメータのBOOLの宣言を無視したようにRubyは型の宣言は一切ないので落としてしまいます。

ターゲットにメッセージを送るの書き換え

Rubyの文法が拡張されていてパラメータ名の指定に対応されています。 (Ruby1.9の簡易Hash指定とどう区別してるのだろう...)

括弧は省略してもかまいません。

target.message3 arg1, with:arg2

クラスメソッドも同様ですので、よく見るオブジェクトの生成は

@propertyはインスタンス変数

@property指定はそのクラスのメンバーなのでRubyではインスタンス変数として扱うのが適切だと思います。

@synthesizeはattr_accessor

@synthesizeはsetter/getter生成の指定なのでRubyではattr_accessorにするのが適切だと思います。オプションによってはattr_reader/attr_writerで指定する方が適切かもしれません。

ちなみに、RubyMotionでattr_accessorを使用すると通常のrubyのアクセサ(property,property=)の他にsetPropertyというsetterも生成されます。

このsetProperty、property=と同じなのかと思いきや

cオブジェクト自身を返してます。メソッドチェーンできると言うことですね!

定数の最初の文字に気をつけよう

iOS SDKの定数は小文字から始まりますがRubyMotionではRubyの規約にあわせて大文字から始まるように変換されています。Objective-Cのソースコードをコピペして修正すると、定数の先頭を大文字にするのを忘れがちです。

エラーメッセージを見れば分かるのですが、慣れてくると見つけたらすぐに大文字にするのが習慣になります。

if文の条件に気をつけよう

Rubyの偽はnilとfalseですがObjective-CはCなので偽は0のみです。
#nilやNULLやNO(BOOL)も値としては0です。

なので、これをそのまま置き換えたらダメ。0以外が真と明示的に書かないといけない。

また、真偽値(BOOL)はObjective-CではYES(1)/NO(0)ですが、すべてtrue/falseに置き換える必要があります。

ファイルの依存関係

RubyMotionではappフォルダの中に入っているRubyソースコードをディレクトリが階層になっていてもすべてコンパイルしてくれますが、コンパイルの順番が単純な辞書順なためファイルを分けると未定義でコンパイルエラーになることがあります。

RubyMotionがリリースされたばかりでまだ情報がほとんどなかった頃は困って全部1ファイルにしたりしていましたが、依存関係をRakefileに書けば大丈夫なのでした。

ところが最近リリースされた1.28から自動で解決するようになったようです。
#が、まだうまく動かないことが多いらしいです(-ω-)

ブロック呼び出し方

Objective-Cにはクロージャを実現するブロック構文があって、アニメーションのコールバックなどでよく使います。lambdaを使います。

#この例は公式ガイドそのものですが...

lambdaじゃなくてprocでも動きますが、procはパラメータ数に無頓着だったりreturnで外側のメソッドを抜けてしまったりObjective-Cのブロックとは違う動きをするのでlambdaの方が安心です。

ポインタ

描画系のAPIを使う場合にCのポインタをライブラリに渡さなければいけないシチュエーションが多々あります。

RubyMotionのPointerを使えばC言語のポインタ操作ができますが、Objective-Cから移植していると、表記方法を混乱しがちなので落ち着いて対応していきましょう。

こういうのでもGLubyte(OpenGLESの型)をXcodeで調べればサイズはunsigned charと分かるので、

とかけます。アクセス方法は配列と同じですが相手はCの配列=メモリエリアなので何を格納するのがプログラムの意図として正しいのかよく考えて移植しましょう。

写経に使えるサンプルコードの紹介

元になるコードはGithubなどでObjective-CやiOSで検索してもたくさん出てくるでしょうが、まずは小さなプログラムから始めたいところです。

私が参考にしたサンプルコードを紹介します。

iOS Developer Library Sample Code

Appleのサンプルコード集です。

cocoa controls for iOS

iOS用のUIパターン実装例が大量にあります。移植したものが動くとかなり嬉しいです。

iOS 6 新機能のサンプルコード/ライブラリのまとめ22個 - Over&Out その後

iOS 6の新機能を紹介したブログエントリーですが、新機能をRubyMotionで実装してみる実験に良さそうです。

まとめ

Objective-Cで実装できていることは、なんでもできる...と言い切れるかはまだ分かりませんが、私がいろいろやってみたサンプルコードではひとつ(OpenELGSを使っているもの)を除いてすべて動きました。

もっといろいろ突っかかった事があった気がするのですが、思い出せたのはこのくらいでした。簡単なことでも気づいたことをブログに書くなどして残しておいた方がいいですね。



トラックバック(0)

トラックバックURL: http://www.iwazer.com/mt/mt-tb.cgi/1161

コメントする

このブログ記事について

このページは、iwazerが2012年12月16日 00:00に書いたブログ記事です。

ひとつ前のブログ記事は「RubyMotion iOS Development with Ruby」です。

次のブログ記事は「RubyMotionでTDDしつつどこまでMetaProgrammingできるかな?の実験」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。