2010年9月13日月曜日

NSRange オブジェクト

AppleScriptObjC では Cocoa が呼び出せるので、Cocoa クラスのインスタンスを作成する時は alloc() すれば済みます。 ところが、NSRange のように、インライン関数 NSMakeRange() を使ってインスタンスを作成するものは、undocumented な部分が多く、よくわかっていません。なお、AppleScript で range と言うと … n thru m … のことですが、これは NSRange ではありません。

NSRange を使うサンプルコードを示します。このコードは、ファイル名のディレクトリ部分を得る ("/usr/local/bin/script.sh" が渡されたとき、"/usr/local/bin" を取得する) ものです。UNIX のコマンドで言うと、dirname に相当します。

property NSString : class "NSString"
property NSFileManager : class "NSFileManager"

on foo(filename)
  set str to ((NSString's alloc())'s initWithString_(filename))'s autorelease()
  set pc to str's pathComponents()
  set rng to {0, (pc's |count|()) - 1}
  set cwd to NSString's pathWithComponents_(pc's subarrayWithRange_(rng))
  set mng to NSFileManager's defaultManager()
  mng's changeCurrentDirectoryPath_(cwd)
end foo

このコードは、以下のように動きます。

  1. ファイル名の文字列 filename を NSString にして、変数 str に代入します。AppleScript で扱っている文字列は NSString ではないことがあるので、NSString の機能を使いたいときは、このような変換をします。
  2. pathComponents() で、str を / ごとに分解した文字列の入った NSArray を取得し、変数 pc に代入します。"/usr/local/bin/script.sh" は [ "/", "usr", "local", "bin", "script.sh" ] に分解されます。
  3. 変数 pc に入っている配列から、最後の要素 "script.sh" を取り除いた NSArray を作ります。この範囲 (0 から、配列の要素数 - 1) を NSRange で指定します。とは言え、単なるリストを作るだけです。リストの第一要素が開始位置、第二要素が長さを表しています。作成したリストを rng に代入しています。
  4. subarrayWithRange_() で、3 で作ったリストで範囲を指定し、配列から必要な部分を取り出します。これを元に新しい NSString を pathWithComponents_() で作成し、変数 cwd に代入します。
  5. NSFileManager を使って、カレントディレクトリを cwd に変更します。

結局、subarrayWithRange_() を呼び出す時に、AppleScriptObjC が強制的に型変換のようなことを行っているようなのですが、この辺のルールがよくわからないのです。とりあえず、動いているのでよしとします。

なお、Cocoa のメソッドを呼び出した時に、NSRange オブジェクトが返却された場合、AppleScriptObjC からはレコードとして見えるので、開始位置は |location| of aRange 、長さは |length| of aRange のようにアクセスします。

0 件のコメント:

コメントを投稿