Linux で Objective C を走らせてみた

Objective C に憧れて

Objective C といえば遠い昔、「この世には Objective C なる変わったオブジェクト指向言語があって、スティーブジョブスの NeXT はそれで動いているらしいよ」と聞いて以来、ずっと憧れの言語であった。世が変わり、NeXT を祖先に持つ MacOS X が一世を風靡し、iPhone 用アプリでさえも Objective C で開発するご時世になって、Objective C は急に脚光を浴び始めた感がある。Objective C は Apple 御用達という雰囲気があるが、実は Linux でも簡単に使うことができる。ソースコード自体は gccコンパイルできるので、後は Objective C 用のライブラリさえあればいい。(と偉そうに書いているがそのことを今日知った)以下、ちょっといじってみた感じを書いてみる。

Objective C の導入 (Debian Linux 編)

私は Debian を使っているので、aptitude を使って Objective C 用のライブラリを導入した。

% sudo aptitude install gobjc

導入するパッケージ名は gobjc で OK。成功すると /usr/lib/libobjc.so.* というファイルがインストールされているのがわかる。

さっそく "Hello World!" プログラムを書いてみる。test1.m という名前で保存する。(Objective C では、ソースコードの拡張子は .m を使うらしい。なんで .m なのか不思議だけど)

#import <objc/Object.h>

int main() {
        printf("Hello World!\n");
        return 0;
}

これは、ほとんど C と同じである。よく見ると、#import という不思議な命令がある。これは Objective C 固有のものである。

% gcc test1.m -lobjc
% ./a.out
Hello World!

やった!生まれて初めての Objective C プログラムである!

情報ソース

かんたんObjective-C
このエントリの元ネタ。簡潔にまとまっていてよい。

Objective-C入門
もうちょっと詳しく知りたい人のために。

Objective C 風のクラス定義

Objective C は、その名の通り、オブジェクトを扱わなければ存在価値が出てこない。では早速オブジェクトを定義してみる。

// test2.m
#import <objc/Object.h>

@interface Animal: Object {
        int weight;
}
-setWeight :(int) w;
-(int) getWeight;
@end

@implementation Animal
-setWeight :(int) w { weight = w; return self; }
-(int) getWeight { return weight; }
@end

int main() {
        id animal = [Animal alloc];
        [animal setWeight: 100];
        printf("%d\n", [animal getWeight]);
        return 0;
}

私は、畜産業者か何かだろうか?動物(Animal) の体重を管理するというきわめて単純なプログラムである。@interface やら @implementation やら、いかにも C ぽくない代物が出てきた。なんだかワクワクするね(笑)これを見て、私は昔書いた Borland Delphi のプログラムを思い出した。あの言語も Objective Pascal と呼ばれていたっけ。Delphi は素晴らしい開発環境だったのになあ・・・当時、結局主流になったのは Microsoft Visual Basic という〇〇な言語だった・・・。

閑話休題

これを解説すると・・・。

@interface Animal: Object {
        int weight;
}
-setWeight :(int) w;
-(int) getWeight;
@end

これは Animal クラスの宣言。本当は C++ みたいに *.h という拡張子をもつヘッダファイルに書くらしいが、とりあえず面倒なので *.m というソースファイルに含めてしまった。Animal の後の ": Object" は Object クラスを継承することを意味する。そして { } の中には、インスタンス変数を宣言する。

その後に続くのが、メソッド定義。最初の "-" はインスタンスメソッドを意味し、"+" とすればクラスメソッドを意味するらしい。() の中には型を書く。":" の後には引数を書く。したがって、上のメソッド宣言を日本語で書くと、

int 型の引数 w を持つ setWeight というインスタンスメソッド(戻り値は省略 = id 型)
引数のない、戻り値が int 型の getWeight というインスタンスメソッド

ということになる。

つぎに、クラス実装部。

@implementation Animal
-setWeight :(int) w { weight = w; return self; }
-(int) getWeight { return weight; }
@end

シグネチャの部分は宣言部と同じで、実装を引き続き {} の中に書くだけ。引数を省略した場合、self (これは id 型) を返すのがお約束らしい。

後は、プログラムのエントリポイント。

int main() {
        id animal = [Animal alloc];
        [animal setWeight: 100];
        printf("%d\n", [animal getWeight]);
        return 0;
}

いかにも C ぽいコードのなかに唐突に [ ] で囲まれた領域が現れるのが素敵すぎる。[Animal alloc] において、クラスメソッド alloc を使って Animal オブジェクトを生成。これは Ruby が new というクラスメソッドを使ってオブジェクトを作るのにそっくりだね。[animal setWeight: 100] は、Ruby 風に書けば animal.setWeight(100) という感じか。なんか Smalltalk の香りがする。いかにも animal オブジェクトに setWeight というメッセージを送ってるという感じだ。

というわけで、[ ] がいままで個人的には謎だったのだが、要するにオブジェクトへのメッセージ送信だったわけね。なるほど。C はもともと「高級なアセンブラ」と呼ばれるような低級な言語で、それに Lisp に並ぶ超高級言語である Smalltalk の味わいが持ち込まれているという強烈なハイブリッド感がたまらない。なんだか、これだけで Objective C のファンになってしまいそうだ。

今年中にはなんとか Mac を購入するつもりなので、そしたら Objective C を使って何か開発してみようかな・・・。