Java : java.io.File
[id:lethevert:20060908:p3]の続き
File#getCanonicalPath()を取ってみたら、意図しているディレクトリより上のディレクトリを指していることが判明。
調査続行。
-
-
- -
-
クラスライブラリを直接確認する方が早そうだと、JODEでFileクラスの実装を確認しようとしたら、NoClassDefFoundErrorが・・・
-
-
- -
-
よく考えたら、jdk1.5は、ソースつきでインストールしていたので、展開して確認。とりあえず、これを書いた人は8タブ派であることを確認。
-
-
- -
-
やはり、JNIで書かれていて、実装の詳細は確認できず。概要は、getCanonicalPath()は、getAbsolutePath()をcanonicalizeして得ているようだ。canonicalizeの動作の詳細は、FileSystemクラスで定義されていて、これがプラットフォームごとにサブクラスが定義されていて、その部分がJNIで実装されているという具合。
-
-
- -
-
なぜかよく分からないけれど、
File f = new File(currdir, String.valueOf(p));
と書く代わりに
File f; try{ f = new File(currdir.getCanonicalPath(),String.valueOf(p)); }catch(IOException _){ f = new File(currdir, String.valueOf(p)); }
と書くことで、現象を回避。やっぱりバグくさいなぁ。
-
-
- -
-
完全解明しました。
http://lethevert.blogspot.com/2006/09/strange-behaviour-of-javaiofile.html
Haskell : モナド
[id:lethevert:20060908:p1]の実装は、なんとなくもっともらしいのですが、実際には、HaskellのIOモナドの実装とは違う挙動を示します。(これは、先にk.inabaさんの指摘で気づいたことですが)
次のような関数を定義して実行すると、
start2 :: () start2 = let A a = k in a where k = print2 "Hello " `seq` print2 "World!"
結果は
MyIO> start2 Hello World! ()
となりますが、同じことをIOモナドでやると
MyIO> putStrLn "Hello " `seq` putStrLn "World!" World!
となり、"Hello "は出力されません。
これを見て、Haskellの入出力を効率的に実装するアイデアが思いつかないなーと思っているのが、今の状況なわけです。