PerlエンジニアのためのObjective-C Blocks入門
OS X 10.6 以降の xcode では Objective-C に Blocks というシンタックスが追加されている。
Perl でいうところの無名関数(コードブロック)を作ることができる機能で、Perlでいうところの
my $f = sub { ... };
$f->();
は
void (^f)() = ^{ ... };
f();
のように書ける。書式がきもいのはObjective-Cの定めなのであきらめましょう。 より詳しい書式については上記ドキュメントを見ると良い。
しかしデフォルトではPerlのコードブロックとはレキシカル変数の扱いが異なる。
my $i = 0;
my $f = sub { return $i + 1 };
$i++;
$f->(); # 2 を返す
perlではこのようにレキシカル変数はコードブロック内と共有されるが、Objective-Cの場合は
int i = 0;
int (^f)() = ^{ return i + 1; };
i++;
f(); // 1 を返す
このようになる。これはブロックを作成するときのレキシカル変数がコピーされるからである。 Perlとおなじような挙動を望む場合は __block
ストレージタイプを指定すればいいようだ。
__block int i = 0;
int (^f)() = ^{ return i + 1; };
i++;
f(); // 2
ここまでわかればObjective-CでBlockの再帰を書くことができる。
__block void (^f)();
f = ^{ f(); };
f();
これは以下とおなじ、
my $f;
$f = sub { $f->() };
$f->();
というようにPerlエンジニアにとっては割と直感的なコードブロックが使えるようになっております。 書式がきもいことをのぞけばいい感じです。
次回は「PerlエンジニアのためのGrand Central Dispatch」の予定です。
追記@2010-05-11T19:12:48+09:00
はてなブックマーク - PerlエンジニアのためのObjetive-C Blocks - unknownplace.org
lyokato 「Objective-Cの仕様というよりは、Blocks拡張に対応したCコンパイラの仕様かな」
ってことでやってみたら
#include <stdio.h>
int main(int argc, char** argv) {
void (^f)() = ^{ printf("Hello Blocks!\n"); };
f();
return 0;
}
// $ gcc foo.c
// $ ./a.out
でも行けました。gcc の拡張なんですね。あざっす!