きりかノート 3冊め

おあそびプログラミング

XcodeでRubyCocoaプロジェクトを実行すると"invalid option"とログに出力され起動しない

現象

@casualconc さんから「RubyCocoaのプロジェクトをビルドして実行するとinvalid option -Nとでる」とのこと。アプリ単独では実行できるが、Xcodeからの実行ができない。

調査

ぴんときた。

 % ruby -N
 ruby: invalid option -N  (-h will show valid options)

んー、これですな。RubyCocoaでは、.app実行時に渡されたオプションをrubyコマンドラインオプションとして解釈するように設計されている(RBApplicationMain()を使っている場合のみ)。なのでXcodeがオプションを渡して実行してしまって、それがrubyにない値だとエラーになってしまう。リフジン。

確認するために新規プロジェクトを作成して、実行時の引き数を出力してXcode 4.2で実行みる。

 - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
 {
     NSProcessInfo * info = [NSProcessInfo processInfo];
     NSLog(@"number of arguments: %lu", [[info arguments] count]);
     [[info arguments] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
  NSLog(@"arguments[%lu]: %@", idx, obj);
     }];
 }

出力はこんな感じ。

 [62066:707] number of arguments: 3
 [62066:707] arguments[0]: /.../A.app/Contents/MacOS/A
 [62066:707] arguments[1]: -NSDocumentRevisionsDebugMode
 [62066:707] arguments[2]: YES

ということで"-NSDocumentRevisionsDebugMode YES"というのが渡されているようだ。これは、SchemeのRun>Options tab: "allow debugging when using document Versions Browser"のオンオフで制御できるけれど初期値がオンみたい。

さて、Apple側でこれに関した情報はないかと見てみると、Mac OS X Lion Release Notes
Cocoa Application Frameworkの"NSDocument Autosaving In Place"にそれっぽい記述がある。

Since the version browser interface takes control of the entire screen,
you can set the NSDocumentRevisionsDebugMode user default to YES for
easier debugging of your application in this interface.

ほかにも"-NSTableRowViewShowRows YES"や"-NSOutlineViewValidateChanges YES"を渡すと…的な記述があるので同類なのでしょう。

検討

ようするになんでもrubyのオプションとして解釈してしまうのが問題。

  • そもそもrubyに渡さない。今まで-dとかがよく使われていたけれど、それらはRUBYOPT経由などにしてもらう。
  • たとえば"-NS"ではじまるものは無視するようにする。今は"-psn"だけ処理している。

前者だな。そもそもこの機能はあんまし良くないと思ってたし。アプリでコマンドオプション渡されたときのみ別の動きをするみたいのがRubyCocoaだとつくりづらいんだよね。

ということで手を入れてコミット。

  • main()に渡されたargcを解釈せずNSApplicationMain()に渡すように。(r2332)
  • プロジェクトテンプレートが旧APIのRBApplicationMain()を使っていたので、RBApplicationInit()とNSApplicationMain()の処理に。新しいほうだとNSApplicationMain()にargcが渡せる。(r2333)