2012-10-02 17 views
9

Czytam in the API docs, że zmienna *file* powinna mieć wartość "ścieżki ocenianego pliku, jako ciąg". Jednak w niektórych przypadkach ta funkcja wydaje się być uszkodzona.* plik * zmienna nie działa

Kiedy wykonać plik, używając lein exec, wszystko działa zgodnie z oczekiwaniami:

$ cat test.clj 
(println *file*) 
$ lein exec test.clj 
/path/to/test.clj 

Jednak kiedy uruchomić test, który zawiera wezwanie do (println *file*), NO_SOURCE_PATH jest drukowany zamiast pliku zawierającego tę linię.

Dlaczego widzę to zachowanie i jak uzyskać niezawodny dostęp do ścieżki i nazwy pliku ocenianego pliku?

Odpowiedz

13

*file* jest ustawiony do ścieżki pliku będącego skompilowany, więc po całym programie jest skompilowany nie jest już użyteczne, by spojrzeć na wartości *file* (zakładając brak wykorzystania eval).

W przykładzie wykonywany jest plik println podczas kompilacji pliku. Jeśli odwołanie do *file* zostanie przeniesione do testu lub funkcji, zostanie ono zerwane tylko w czasie wykonywania, gdy wartość *file* przestanie być użyteczna.

Jedną z opcji jest zapisanie makra, które przechowuje wartość *file* po rozwinięciu, aby wynik mógł zostać użyty później. Na przykład, plik może mieć example.clj:

(defmacro source-file [] 
    *file*) 

(defn foo [x] 
    (println "Foo was defined in" (source-file) "and called with" x)) 

następnie od REPL lub gdziekolwiek, (foo 42) by wydrukować:

Foo was defined in /home/chouser/example.clj and called with 42 

pamiętać, że nie ma znaczenia, który plik source-file jest zdefiniowana w, tylko gdzie został on rozszerzony, to jest plik, w którym zdefiniowano foo. Działa to, ponieważ kompilacja foo powoduje uruchomienie source-file, a zwracana wartość source-file, która jest tylko łańcuchem, jest następnie dołączana do skompilowanej wersji foo. Ciąg jest oczywiście dostępny za każdym razem, gdy wykonuje się kod foo.

Jeśli to zachowanie jest zaskakujące, może pomóc rozważyć, co by się stało, aby *file* miał użyteczną wartość w każdej funkcji w środowisku wykonawczym. Jego wartość musiałaby ulec zmianie w przypadku każdego wywołania i powrotu funkcji, co jest znacznym obciążeniem dla rzadko wykorzystywanej funkcji.

+0

Świetne wyjaśnienie; Dziękuję bardzo! –

Powiązane problemy