Подтвердить что ты не робот

Что такое Clojure эквивалент __FILE__ (найденный в Ruby & Perl)

В ruby ​​я часто использую File.expand_path(File.dirname(__FILE__)) для загрузки файлов конфигурации или файлов с тестовыми данными. Прямо сейчас я пытаюсь загрузить некоторые html файлы для теста в моем приложении clojure, и я не могу понять, как это сделать без жесткого кодирования полного пути к файлу.

изменить: Я использую leinigen, если это помогает в любом случае

ref: __FILE__ - это специальный литерал, который возвращает имя файла (включая любой путь), предоставленный программе при его выполнении. (rubydoc и perldata)

4b9b3361

Ответ 2

Вот один из способов репликации в Clojure:

(defn dirname [path]
  (.getParent (java.io.File. path)))

(defn expand-path [path]
  (.getCanonicalPath (java.io.File. path)))

Тогда ваша строка Ruby File.expand_path(File.dirname(__FILE__)) в Clojure будет таковой:

(expand-path (dirname *file*))

Смотрите Java interop docs для .getParent и .getCanonicalPath.


NB. Я думаю, что *file* всегда возвращает абсолютный (хотя и не канонический) путь/имя файла в Clojure. В то время как __FILE__ возвращает имя пути/имя файла, предоставленное при выполнении. Однако я не думаю, что эти различия должны влиять на то, что вы пытаетесь сделать?

/I3az/

Ответ 3

Ни одно из 9-точечных решений не является правильным. * file * дает вам файл относительно пути к классам. Использование .getCanonicalPath или .getAbsolutePath в * файле * даст вам неиспользуемый файл. Как указано в этот старый поток, вам нужно использовать ClassLoader для правильного решения * файла *. Здесь я использую, чтобы получить родительский каталог текущего файла:

(-> (ClassLoader/getSystemResource *file*) clojure.java.io/file .getParent)

Ответ 4

Основываясь на ответе user83510 выше, полный ответ:

(def path-to-this-file 
  (clojure.string/join "/" [(-> (ClassLoader/getSystemResource *file*) clojure.java.io/file .getParent) (last (clojure.string/split *file* #"/"))]))

Это не очень, но он работает: P