きりかノート 3冊め

おあそびプログラミング

RubyCocoa 1.0 Sneak Preview

すでにアナウンスされているように、RubyCocoa 1.0 Sneak Prevew として、0.9.0 がリリースされました。ちょっと遅くなってしまったけれど、紹介ページの翻訳をしておきます。一部超訳です、あしからず。

(以下翻訳)

このページは、将来 1.0 リリース版となる RubyCocoa の unstable branch(訳注:apple-unstable-branch)の現状について説明したものです。

今のところ、まだまだ手をいれているものの、機能的な面はほとんど実装されていますし、安定版リリース(訳注:0.5.0)よりも信頼性があるとさえ言えます。そこで、pre-release 版を試すに当たってのご案内をここで提供します。あなたが見つけたどんな問題についてでも、レポートをいただければ幸いです(訳注:ここ2文超訳)。

Getting Started

最新の pre-release は、0.9.0 です。バイナリのインストーラソースコードの両方が用意されています。

ソースコードをダウンロードした場合は、自分で RubyCocoa をビルドする必要があります。

 $ cd rubycocoa-unstable
$ ruby install.rb config
$ ruby install.rb setup
$ sudo ruby install.rb install

また、Subversion リポジトリから最新のコードを入手することもできます。

 $ svn co https://rubycocoa.svn.sourceforge.net/svnroot/rubycocoa/branches/apple-unstable/src rubycocoa-unstable

RubyCocoa をインストールすると、サンプルが /Developer/Examples/RubyCocoa にインストールされています。

What's New

unstable ブランチでは、多くの修正と改善が行われました。重要な変更について説明します。

Libffi Integration

RubyCocoa でも Libffi が導入されました。"FFI" は Foreign Function Interface の略語です。Libffi は、GCC プロジェクトの一部である C言語のライブラリで、あらゆる C言語の関数を実行することができます。agnostic な方法で(なんだかよくわからない方法で? 適した語を教えてください! - 訳者) 引数を格納、返り値を取り出し、変数の型を抽出することで(関数呼び出しが)実行されます。

RubyCocoa は、2つの世界(訳注:Objective-CRuby)間のメッセージ送信において、C 関数や Objective-C のメソッドを Ruby から呼び出しているのに対して、Objective-C からのメッセージ送信では専用の Ruby オブジェクトを経由させています。(訳注:RubyCocoa では、RBObject という Ruby オブジェクトをラップする Objective-C のクラスがあります。このクラスは Cocoa の forward invocation を利用して Objective-C から Ruby メソッドの呼び出しを実装していますが、この機能には、パフォーマンスがあまりよくない、可変引数のメソッドが扱えないなどのデメリットがあります)

RubyCocoa での Libffi の使用は、信頼性とパフォーマンスの向上をもたらしました。RubyCocoa では NSInvocation はもはや利用されていません。

BridgeSupport Metadata

Objective-C の動的性質のおかげで、ブリッジの提供に必要な情報(クラスやそのメソッドなど)は実行時に取得することができます。しかしながら、Objective-C 中の C の部分は動的なものではないために、関数や定数といった C のデータを実行時に知ることはできません。

RubyCocoa では、これらの C の要素を扱うために、ビルド時にヘッダファイルをパースすることにより静的なコードを生成していました。ですが、これは新しいフレームワークのサポートを追加したときに(訳注:RubyCocoa を)再ビルドしなければならないなど、保守性を低下させることにもなってしまいました。ですから、静的なコードではなくメタデータにより Cの要素を扱うというアイディアが実現されました(訳注:この文超訳)。われわれ開発者が用意しておいたメタデータファイルを、RubyCocoa は実行時に解釈します。

メタデータを生成するスクリプトが提供されており、ビルド時にはこのスクリプトによりデフォルトのフレームワークに関するメタデータが生成されます。メタデータファイルは XML 形式で、フレームワークごとに1ファイルとなります。メタデータは、C の関数、enum、定数、構造体、さらには opaque や Core Foudation の型、Objective-C の非定型プロトコルに関する情報を表現します。メタデータは、メソッドの返り値の BOOL 型(訳注:BOOL は内部的に unsigned char で 表現されるため、Objective-C のランタイムから、あるメソッドの返り値が BOOL であるかどうかを判断することができません)や、ポインタ渡しの引数による返り値に関しての情報も提供します。

RubyCocoa は、フレームワークのロード完了後にメタデータファイルを読み込みます。そのため、必要なときだけローカライズされたシンボルを扱うなど、メタデータの寛容な解釈を行うことができます。より多くのフレームワークをサポートすることができるように、メタデータ生成スクリプトは /usr/bin/gen_bridge_metadata としてインストールされます。また、メタデータファイルは /Library/BridgeSupport にインストールされます。

More Frameworks Support

新しいメタデータ機構のおかげで、以前よりも簡単にフレームワークのブリッジを提供することができるようになりました。今までの Foundation, AppKit と WebKit に加えて、unstable ブランチでは CoreFoundation, CoreGraphics, PDFKit, QuartzCore (CoreImage と CoreVideo), OpenGL, QTKit をサポートしています。今後もさらなるフレームワークのサポートを進めていきます。

Syntax Changes

RubyCocoa では、Objective-C のメッセージを Ruby で扱う際に、最後のアンダースコアを省略することができました。これは現在ではサポートされていますが、 OSX.relaxed_syntax の値が false のときには許可されない記法となります。(OSX.relaxed_syntax の初期値は true)

 p OSX.relaxed_syntax                # returns true
OSX::Array.arrayWithObject('foo') # OK
OSX.relaxed_syntax = false
OSX::Array.arrayWithObject('foo') # Exception!
OSX::Array.arrayWithObject_('foo') # OK

Ruby から Objective-C にメッセージ送信するときの、symbol / value... という記法は利用できなくなりました。この記法を利用した呼び出しを行う都度、警告が出力され、最終リリース時には例外が発生するようになります。

 OSX::NSURL.alloc.initWithScheme('http', :host, 'www.apple.com', :path, '/macosx')  # BAD
OSX::NSURL.alloc.initWithScheme_host_path('http', 'www.apple.com', '/macosx') # GOOD

RubyCocoa では、C の定数を RubyOSX モジュールの定数であるかのように扱うことができます。以前のバージョン(訳注:0.4.2まで)では、OSX モジュールのメソッドのようになっていました。OSX モジュールのメソッド形式での定数アクセスは、今後廃止されます。現在では、メソッド呼び出しの都度警告が出力され、最終リリースでは例外が発生するようになります。

 OSX.NSApp    # BAD
OSX.NSApp() # BAD
OSX::NSApp # GOOD

Support

今のところは、rubycocoa-devel メーリングリストでフィードバックを受け付けています(訳注:日本語での投稿は rubycocoa メーリングリストへお願いします)。バグトラッカーは現在準備中です。

(おわり)