*file*
se establece en la ruta del archivo que se compilan , así que después de todo se compila el programa ya no es útil mirar el valor de *file*
(suponiendo que no hay uso de eval).
En su ejemplo test.clj
, se ejecuta println
mientras el archivo todavía se está compilando. Si la referencia a *file*
se mueve a una prueba o función, solo se eliminará la referencia en el tiempo de ejecución después de que el valor de *file*
ya no sea útil.
Una opción es escribir una macro que almacena el valor de *file*
cuando se expande, por lo que el resultado se puede utilizar más adelante. Por ejemplo, un archivo example.clj
podría tener:
(defmacro source-file []
*file*)
(defn foo [x]
(println "Foo was defined in" (source-file) "and called with" x))
Luego, desde el REPL o en cualquier lugar, (foo 42)
imprimiría:
Foo was defined in /home/chouser/example.clj and called with 42
Tenga en cuenta que no importa qué archivo se define en source-file
, sólo cuando fue expandido, ese es el archivo donde se define foo
. Esto funciona porque es cuando se compila foo
que se ejecuta source-file
, y el valor de retorno de source-file
que es solo una cadena se incluye en la versión compilada de foo
. Por supuesto, la cadena está disponible cada vez que se ejecuta foo
.
Si este comportamiento es sorprendente, puede ser útil considerar lo que debería suceder para que *file*
tenga un valor útil dentro de cada función en tiempo de ejecución. Su valor tendría que cambiar para cada llamada y retorno de función, una sobrecarga de tiempo de ejecución sustancial para una característica rara vez utilizada.
Gran explicación; ¡muchas gracias! –