RubyとObjective-Cの黒魔術の比較

自己紹介

名前
和泉田 領一
愛称
りず
Twitter
@rizumita
所属
株式会社Lang-8
住んでるところ
安曇野市
会社ではHiNativeという言語や文化のQ&AサービスのiOSアプリを開発してます。

黒魔術

以下の項目は調べた範囲で、Rubyでできる黒魔術です。これらについてRubyとObjective-Cとを比べてみます。

参考文献

メソッドを実行時に生成

Rubyの場合
Rubyはインタプリタ言語なので実行時に一般的な書式でメソッドが生成されます。例えば以下のように定義されます。
foo(123) #=> エラー
def foo(v)
end
def bar(v)
end
bar(123) #=> OK

Objective-Cの場合
以下#import <objc/runtime.h>を必要とします。
コンパイル言語であるObjective-Cでは実行時に一般的な定義書式でメソッドを定義することはできません。
しかし一般的でない方法であればObjective-Cでもメソッドを生成することが可能です。
Objective-CにはC言語の関数とObjective-Cオブジェクトのメソッドが存在します。上記のRubyコードにおけるメソッドは一見するとObjective-Cにおける関数のようですが、RubyのトップレベルはObjectクラスのmainインスタンスですので、一応Objective-Cにおけるオブジェクトのメソッドと捉えられます(トップレベルがObjectのmainなのは方便のようなものみたいですが)。Objective-Cにはトップクラスはありませんがクラスにメソッドを動的に追加することは可能です。

IMP imp = imp_implementationWithBlock(^(void) { NSLog(@"myMethod"); });
class_addMethod(NSString.class, sel_registerName("myMethod"), imp, "v@:");
[@"String" performSelector:@selector(myMethod)];

IMPは実装です。class_addMethodでNSStringクラスにmyMethodというメソッド名で実装を追加しています。最後の行はメソッドの呼び出し例です。一般的なメソッドであれば[@"String" myMethod]とメッセージを送ることができるのですが、ARCというメモリー管理方式になってからperformSelectorでしか呼び出せなくなりました。
class_addMethodの最後のv@:Type Encodingsに書式があります。メソッドの引数と戻り値の型を表現します。理解しがたいですが仕方ありません。
総じてRubyの方が定義しやすいといえます。