*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.
Świetne wyjaśnienie; Dziękuję bardzo! –