namespaces clojure compilation

namespaces - Dividir un espacio de nombre Clojure en varios archivos



compilation (1)

Visión de conjunto

Ciertamente usted puede, de hecho, el espacio de nombres clojure.core mismo se divide de esta manera y proporciona un buen modelo que puede seguir buscando en src/clj/clojure :

core.clj core_deftype.clj core_print.clj core_proxy.clj ..etc..

Todos estos archivos participan para crear el espacio de nombres único clojure.core .

Archivo principal

Uno de estos es el archivo principal, cuyo nombre coincide con el nombre del espacio de nombres para que se encuentre cuando alguien lo menciona en a :use o :require . En este caso, el archivo principal es clojure/core.clj , y comienza con un formulario ns . Aquí es donde debe colocar toda su configuración de espacio de nombres, independientemente de cuáles de sus otros archivos puedan necesitarlos. Esto normalmente incluye :gen-class también, algo así como:

(ns my.lib.of.excellence (:use [clojure.java.io :as io :only [reader]]) (:gen-class :main true))

Luego, en los lugares apropiados en su archivo primario (más comúnmente al final) use load para traer sus archivos auxiliares. En clojure.core se ve así:

(load "core_proxy") (load "core_print") (load "genclass") (load "core_deftype") (load "core/protocols") (load "gvec")

Tenga en cuenta que no necesita el directorio actual como prefijo, ni necesita el sufijo .clj .

Archivos de ayuda

Cada uno de los archivos auxiliares debe comenzar por declarar qué espacio de nombres están ayudando, pero debe hacerlo utilizando la función in-ns . Entonces, para el espacio de nombres de ejemplo anterior, los archivos auxiliares comenzarían todos con:

(in-ns ''my.lib.of.excellence)

Eso es todo lo que se necesita.

gen-class

Debido a que todos estos archivos están creando un solo espacio de nombres, cada función que defina puede estar en cualquiera de los archivos primarios o auxiliares. Esto, por supuesto, significa que puede definir sus funciones gen-class en cualquier archivo que desee:

(defn -main [& args] ...)

Tenga en cuenta que las reglas de orden de definición normales de Clojure aún se aplican a todas las funciones, por lo que debe asegurarse de que cualquier archivo que define una función se cargue antes de intentar usar esa función.

Vars Privados

También preguntaste sobre el (defn- foo ...) que define una función privada del espacio de nombres. Funciones definidas de la siguiente manera :private vars :private son visibles desde el espacio de nombres donde están definidos, por lo que los archivos primarios y todos los helper tendrán acceso a vars privados definidos en cualquiera de los archivos cargados hasta el momento.

¿Es posible dividir un espacio de nombres de Clojure sobre varios archivos de origen al hacer una compilación anticipada con :gen-class ? ¿Cómo (defn- ...) (:main true) y (defn- ...) entran en juego?