檜山正幸のキマイラ飼育記 このページをアンテナに追加 RSSフィード Twitter

キマイラ・サイトは http://www.chimaira.org/です。
トラックバック/コメントは日付を気にせずにどうぞ。
連絡は hiyama{at}chimaira{dot}org へ。
蒸し返し歓迎!
このブログの更新は、Twitterアカウント @m_hiyama で通知されます。
Follow @m_hiyama
ところで、アーカイブってけっこう便利ですよ。

2009-01-19 (月)

Rhinoに基本ディレクトリコマンドを実装する

| 09:48 | Rhinoに基本ディレクトリコマンドを実装するを含むブックマーク

ErlangのEShellでは、pwd(), cd(Dir), ls() という3つの基本的なディレクトリコマンドが備わっています。単純な機能しか持っていませんが、ないよりはずっとましです。

Javaで実装された対話的JavaScript処理系Rhinoには、ディレクトリコマンドがありません。Erlangのpwd(), cd(Dir), ls()と同等の関数を書くことにしました。

pwdコマンド

Javaでカレントディレクトリ(の名前文字列)を得るには次の方法があります。

  1. System.getProperty("user.dir");
  2. (new File(".")).getCanonicalPath();

Rhinoでも、どちらの方法も使えます。

まずは一番目の方法; Rhinoでは、システムプロパティの値が大域変数(値はオブジェクト)environmentに入っているので、次のようにすればOK。

function pwd() {
 var cwd = environment["user.dir"];
 print(cwd);
}

二番目は次のよう。

function pwd() {
 var cwd = (new java.io.File(".")).getCanonicalPath();
 print(cwd);
}

RhinoからJavaのクラスを参照するときは、パッケージ名も付けたフルネームを使います。Fileオブジェクトには、getAbsolutePath()というメソッドもありますが、これだとディレクトリ名の最後に「\.」または「/.」が付いてしまうので具合がよくありません。

カレントディレクトリ文字列を他の関数で使いたいことがあるので、次のgetCwd()も定義しておきます。

function getCwd() {
 return environment["user.dir"];
}

cdコマンド

システムプロパティのfile.separatorの値は、environment["file.separator"] として取れます。あとは、Javaで書く場合とほとんど同じです。([追記]以下のコード、ほんのチョビット修正[/追記]

function cd(dirName) {
 var sep = environment["file.separator"];
 if (dirName[0] != sep) {
  dirName = getCwd() + sep + dirName;
 }
 var newDir = new java.io.File(dirName);
 if (!newDir.exists()) {
  print("not exist: " + newDir);
  return;
 }
 if (!newDir.isDirectory()) {
  print("not a directory: " + newDir);
  return;
 }
 environment["user.dir"] = newDir.getCanonicalPath();
}

lsコマンド

ディレクトリを表すFileオブジェクトのlistFiles()メソッドを使います。listFiles()で得られた配列をそのまま表示するとフルパスが出てちょっとうっとうしいので、baseName関数で短くしています。

function ls() {
 var curDir = (new java.io.File(getCwd()));
 var list = curDir.listFiles();
 for (var i = 0; i < list.length; i++) {
  print(baseName(list[i].toString()));
 }
}

function baseName(path) {
 var sep = environment["file.separator"];
 var i = path.lastIndexOf(sep);
 return path.substring(i + 1);
}

シェルのlsコマンドに比べると貧弱です。必要なら機能拡張してみてください。

[追記]pwdやcdを作っても、もともとの目的は達成されませんでした。その目的とは、loadやreadFileのデフォルトディレクトリを変えることです。Javaのレベルでuser.dirを変更しても、Rhinoが保持している(と思われる)デフォルトディレクトリに影響はないようです。残念。[/追記]

内海内海 2009/01/23 12:46 檜山さんこんにちは。
>若い女性が戦国武将のファン

あ、これに関しては檜山さんとは違って私ちょっと理解出来るかも。
例えば京都にある近藤勇の墓とか、新撰組ゆかりの地に訪れた新撰組ファンの人が感想を書き込むノートが置いてあるんですけど、若い女の子の字で「土方さん惚れました!」とか、少女マンガ風の美形に描かれた新撰組隊士のイラストが結構な数あったりします。
彼女たちにとっては戦国武将や新撰組といった歴史上の人物も、アニメやゲームやマンガのキャラも同じように感情移入出来る存在なんだろうなとは思うんですけど。

m-hiyamam-hiyama 2009/01/23 14:24 内海さん、
> 彼女たちにとっては戦国武将や新撰組といった歴史上の人物も、アニメやゲームやマンガのキャラも同じように感情移入出来る存在なんだろうなとは思うんですけど。

その理屈は分かるんですよ、理屈としては。ニュースでは、武将グッズとかも売れているらしいし、武将トークで盛り上がったりするらしい。そこんところの実感がどうも湧かなくて、、、不思議に思えてしまいます。