Shammer's Philosophy

My private adversaria

動作中にCurrentDirectoryを取得

ccl::get-user-home-dirの方がいい場合 - Shammerismの続き。Lisp の動作中に CurrentDirectory を取得。CurrentDirectory と言っても、プロセスを起動したディレクトリのことではない。説明が難しいけれども、ある関数を実行中にその関数が記述されているソースコードがどこにあるのか、というのを取得したい。これができればファイルのロードに役立つのではないかと。要は、ダイナミックローディングをしたい。ある一つのファイルAをロード、ファイルAのロード中にファイルBをロード、、、というようにしたい。普通にやるとロードの起点は最初のファイルAをロードしたディレクトリになる。ここでロード対象のファイルのPathを全て管理してもいいのだけれども、それをせずにロード途中のファイルから相対Pathで次のファイルをロードするようにしたい、というのが狙い。

重要なのは以下のポイント。

  • (truename ".") でこれが記述されたファイルの Current Directory を取得できる
  • (pathname-directory (truename ".")) で、これが記述されたファイルの絶対 Path の階層リスト(具体例は後述の実行例、current-dir)を取得できる
  • 絶対 Path の階層リスト X に (append X (list "add-dir1" "add-dir2")) とすることでディレクトリの指定ができる
  • 上記で取得したディレクトリ Z に (merge-pathnames Z "load-file.lisp") でロードしたいファイルを動的に指定できる

以下、順序を追って実行。

? (defvar current-dir (pathname-directory (truename ".")))
CURRENT-DIR
? CURRENT-DIR
(:ABSOLUTE "Users" "user1" "Workspace" "test")
? (defvar target-dir (append current-dir (list "add-dir1" "add-dir2")))
TARGET-DIR
? target-dir
(:ABSOLUTE "Users" "user1" "Workspace" "test" "add-dir1" "add-dir2")
? (defvar load-file
    (merge-pathnames
      (make-pathname :directory target-dir)
      (file-namestring "load-file.lisp")))
LOAD-FILE
? load-file
#P"/Users/user1/Workspace/test/add-dir1/add-dir2/load-file.lisp"
?

自環境には実際に上記のファイルは存在しないけれども、手順はこんな感じ。