PerlエンジニアのためのObjective-C Blocks入門

OS X 10.6 以降の xcode では Objective-C に Blocks というシンタックスが追加されている。

Blocks Programming Topics: Introduction

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 の拡張なんですね。あざっす!

by typester / at 2010-05-11T14:29:00 / objc · perl / Comments(0)