Hatena::ブログ(Diary)

Watsonのメモ RSSフィード

2010-03-05

Objective-CからMacRubyを利用する

MacRuby 0.4から、Objective-CでMacRubyを利用するためのAPIが公開されています。このAPIを使用すれば、アプリケーションにplugin機構を比較的容易に導入できるかと思います。pluginをrubyで書けて楽ですし、MacRubyだからCocoaも使えるし(^ ^)

とりあえず、試してみました。MacRubyを利用する際には、GCを有効にする必要があるため、コンパイルオプションに-fobjc-gcを追加します。

  • objc-macruby.m
/* filename : objc-macruby.m */
#import <Foundation/Foundation.h>
#import <MacRuby/MacRuby.h>

int main(void) {
  id ruby;

  ruby = [[MacRuby sharedRuntime] evaluateString:@"puts 'test'"];
  ruby = [[MacRuby sharedRuntime] evaluateFileAtPath:@"fib.rb"];

  NSLog(@"%@", [ruby performRubySelector:@selector(main:) withArguments: @"31", NULL]);
  return 0;
}
  • fib.rb
# -*- coding: utf-8 -*-
# filename : fib.rb

def main(n = 0)
  return fib(n.to_i)
end

def fib(n)
  return 0 if(n == 0)
  return 1 if(n == 1)
  return fib(n - 1) + fib(n - 2)
end
  • 実行結果
$ gcc objc-macruby.m -framework Foundation -framework MacRuby -fobjc-gc
$ ./a.out
test
2010-03-05 02:45:42.575 a.out[32755:903] 1346269


以下を追記しました。

  NSLog(@"%@", [ruby performRubySelector:@selector(main:) withArguments: (id)31, NULL]);

とwithArgumentsに数値を指定すると

$ ./a.out
test
unknown: [BUG] Segmentation fault
MacRuby version 0.6 (ruby 1.9.0) [universal-darwin10.0, x86_64]

zsh: abort      ./a.out

セグメンテーションフォールトで落ちてしまうので @"31" とNSStringで引数を渡していました。

NSNumberに数値を詰め込んで渡せば良かったということがわかりました。

/* filename : objc-macruby.m */
#import <Foundation/Foundation.h>
#import <MacRuby/MacRuby.h>

int main(void) {
  id ruby;

  ruby = [[MacRuby sharedRuntime] evaluateString:@"puts 'test'"];
  ruby = [[MacRuby sharedRuntime] evaluateFileAtPath:@"fib.rb"];

  NSNumber *num = [NSNumber numberWithInt: 31];
  NSLog(@"%@", [ruby performRubySelector:@selector(main:) withArguments: (id)num, NULL]);
  return 0;
}

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/Watson/20100305/1267724607
Connection: close