Est-il possible de diviser un espace de noms Clojure sur plusieurs fichiers source lors de la compilation à l'avance avec :gen-class
? Comment faire (:main true)
et (defn- ...)
entrer en jeu?
Réponses:
Vous pouvez certainement, en fait, l' clojure.core
espace de noms lui-même est divisé de cette manière et fournit un bon modèle que vous pouvez suivre en regardant dans src/clj/clojure
:
core.clj
core_deftype.clj
core_print.clj
core_proxy.clj
..etc..
Tous ces fichiers participent à la construction du single clojure.core
espace de noms .
L'un de ces fichiers est le fichier principal, nommé pour correspondre au nom de l'espace de noms afin qu'il soit trouvé lorsque quelqu'un le mentionne dans un fichier :use
ou :require
. Dans ce cas, le fichier principal est clojure/core.clj
, et il commence par un ns
formulaire. C'est là que vous devez placer toute la configuration de votre espace de noms, quels que soient vos autres fichiers qui en ont besoin. Cela inclut normalement :gen-class
aussi, donc quelque chose comme:
(ns my.lib.of.excellence
(:use [clojure.java.io :as io :only [reader]])
(:gen-class :main true))
Ensuite, aux endroits appropriés de votre fichier principal (le plus souvent à la fin), utilisez load
pour importer vos fichiers d'aide. En clojure.core
cela ressemble à ceci:
(load "core_proxy")
(load "core_print")
(load "genclass")
(load "core_deftype")
(load "core/protocols")
(load "gvec")
Notez que vous n'avez pas besoin du répertoire courant comme préfixe, ni du .clj
suffixe.
Chacun des fichiers d'assistance doit commencer par déclarer l'espace de noms qu'il aide, mais doit le faire en utilisant la in-ns
fonction. Ainsi, pour l'exemple d'espace de noms ci-dessus, les fichiers d'assistance commenceraient tous par:
(in-ns 'my.lib.of.excellence)
C'est tout ce qu'il faut.
Étant donné que tous ces fichiers créent un espace de noms unique, chaque fonction que vous définissez peut se trouver dans l'un des fichiers principaux ou auxiliaires. Cela signifie bien sûr que vous pouvez définir vos gen-class
fonctions dans n'importe quel fichier de votre choix:
(defn -main [& args]
...)
Notez que les règles normales d'ordre de définition de Clojure s'appliquent toujours à toutes les fonctions, vous devez donc vous assurer que tout fichier définissant une fonction est chargé avant d'essayer d' utiliser cette fonction.
Vous avez également posé des questions sur le (defn- foo ...)
formulaire qui définit une fonction d'espace de noms privé. Les fonctions définies comme celle-ci ainsi que d'autres :private
variables sont visibles depuis l'espace de noms dans lequel elles sont définies, de sorte que les fichiers principaux et tous les fichiers auxiliaires auront accès aux variables privées définies dans l'un des fichiers chargés jusqu'à présent.