Section courante

A propos

Section administrative du site

Le REPL et les principaux points d'entrée

L'espace de noms clojure.main

L'espace de noms clojure.main fournit des fonctions permettant de lancer des programmes Clojure et des sessions interactives via l'outil de lancement d'applications Java, java.

clojure.main --help

Le point d'entrée clojure.main/main accepte divers arguments et options.

Les options d'initialisation peuvent être répétées et combinées librement, mais doivent précéder toute option principale. L'ajout d'une option d'évaluation avant l'exécution d'un REPL supprime le message d'accueil habituel : «Clojure ~(clojure-version)».

Les chemins peuvent être absolus ou relatifs dans le système de fichiers, ou relatifs au classpath. Les chemins relatifs au classpath commencent par @ ou @/.

Lancement d'un REPL

La manière la plus simple de lancer un REPL Clojure est d'utiliser l'outil de commande clj, appelant clojure.main :

$ clj
Clojure 1.12.0
user=>

Le prompt REPL affiche le nom de l'espace de noms courant (*ns*), étant par défaut «user».

Plusieurs variables spéciales sont disponibles dans le REPL :

L'espace de noms clojure.repl propose plusieurs fonctions utiles pour consulter le code source et la documentation des fonctions disponibles :

Nom Description
doc Affiche la documentation d'une variable à partir de son nom.
find-doc Affiche la documentation de toute variable dont la documentation ou le nom correspond au modèle spécifié.
apropos Renvoie une séquence de définitions correspondant à une expression régulière.
source Affiche le code source d'un symbole.
pst Affiche la trace de la pile d'exécution d'une exception donnée (ou de *e par défaut).

Lancement d'un script

Pour exécuter un fichier contenant du code Clojure comme un script, transmettez le chemin d'accès à ce script à `clojure.main` en tant qu'argument :

clj -M /path/to/myscript.clj

Passer des arguments à un script

Pour passer des arguments à un script, transmettez-les comme arguments supplémentaires lors du lancement de clojure.main :

clj -M /path/to/myscript.clj arg1 arg2 arg3

Les arguments seront fournis à votre programme sous forme de séquence de chaînes de caractères liées à la variable *command-line-args* :

*command-line-args* => ("arg1" "arg2" "arg3")

Affichage d'erreurs

Dans REPL

À partir de Clojure 1.10, les erreurs Clojure sont classées en plusieurs catégories :

Catégorie Description
:read-source Erreur survenant lors de la lecture de caractères dans le REPL ou à partir d'un fichier source.
:macro-syntax-check Erreur de syntaxe détectée dans la syntaxe d'un appel de macro, provenant soit de spec, soit d'une macro levant une IllegalArgumentException, une IllegalStateException ou une ExceptionInfo.
:macroexpansion Toutes les autres erreurs survenant lors de l'évaluation d'une macro sont classées comme erreurs d'expansion de macro.
:compile-syntax-check Erreur de syntaxe détectée lors de la compilation.
:compilation Erreurs non syntaxiques détectées lors de la compilation.
:execution Erreurs survenant lors de l'exécution.
:read-eval-result Erreur survenant lors de la lecture du résultat de l'exécution (applicable uniquement aux REPL lisant le résultat).
:print-eval-result Erreur survenant lors de l'affichage du résultat de l'exécution.

Les exceptions levées lors de toutes les phases (exception :execution) auront des données ex-data associées, contenant une ou plusieurs des clefs suivantes :

Clef Description
:clojure.error/phase Indicateur de phase
:clojure.error/source Nom du fichier (sans chemin)
:clojure.error/line Numéro de ligne (entier)
:clojure.error/column Numéro de colonne (entier)
:clojure.error/symbol Symbole en cours de développement/compilation/appel
:clojure.error/class Symbole de classe à l'origine de l'exception
:clojure.error/cause Message d'erreur relatif à l'exception
:clojure.error/spec Données explain-data pour une erreur de spécification

L'interface REPL clojure.main inclut par défaut la catégorisation et l'affichage des erreurs. Cependant, les différentes étapes de ce processus sont également accessibles aux autres interfaces REPL, notamment les fonctions suivantes :

Fonction Description
Throwable->map Convertit une chaîne d'exceptions en données Clojure.
ex-triage Analyse les données d'exception Clojure pour extraire les informations pertinentes du début et de la fin de la chaîne et les intégrer dans une carte décrivant uniquement les données nécessaires au formatage d'une chaîne d'exception.
ex-str Génère un message adapté à la phase à partir d'un ensemble de données d'exception.

L'interface REPL clojure.main combine ces fonctions dans un pipeline pour produire le message d'exception affiché : (-> ex Throwable->map clojure.main/ex-triage clojure.main/ex-str). D'autres interfaces REPL peuvent utiliser un ou plusieurs éléments de ce pipeline selon leurs besoins lors de la création ou de la personnalisation de l'affichage des exceptions.

En tant que lanceur

Jusqu'à Clojure 1.10.0, lorsque `clojure.main` était utilisé comme lanceur de programme (avec les options `-m`, `-e` ou via un script), les exceptions non interceptées étaient automatiquement affichées avec la trace de pile complète. Dans ce cas, le processus de tri et d'affichage des erreurs décrit précédemment n'était pas appliqué.

À partir de Clojure 1.10.1, les exceptions non interceptées sont désormais gérées et affichées selon le même mécanisme que l'interpréteur interactif Clojure (REPL). La trace de pile complète, les informations d'erreur (`ex-info`) et autres informations sont écrites dans la destination spécifiée par la configuration.

Les trois destinations d'erreur disponibles sont :

Destination d'erreur Description
file Écriture dans un fichier temporaire (par défaut, utilisation de `stderr` en cas d'erreur)
stderr Écriture dans le flux d'erreur standard (`stderr`)
none Aucune destination

Ces cibles d'erreur peuvent être spécifiées soit comme options de `clojure.main`, soit comme propriétés système Java (les options sont prioritaires). Lors de l'appel à `clojure.main` (ou avec l'outil `clj`), utilisez `--report <cible>`. Pour une propriété système Java, utilisez `-Dclojure.main.report=<cible>`.

D'autres programmes peuvent également utiliser cette fonctionnalité, disponible dans `report-error`, qui prend un objet `Throwable` et, optionnellement, la cible (`:target`).

L'espace de noms utilisateur

Par défaut, l'interpréteur interactif Clojure (REPL) démarre dans l'espace de noms utilisateur, généralement utilisé pour l'exploration du code.

L'interpréteur interactif Clojure charge automatiquement les espaces de noms suivants et référence les fonctions suivantes :

Espace de noms Fonctions
clojure.repl source apropos dir pst doc find-doc
clojure.repl.deps add-lib add-libs sync-deps
clojure.java.javadoc javadoc
clojure.pprint pp pprint

Si vous passez à un espace de noms différent (avec in-ns ou ns), ces fonctions ne seront pas disponibles à moins d'y être explicitement référencées.

Chargement de user.clj

L'environnement d'exécution Clojure recherche et charge le fichier user.clj au démarrage, s'il est présent dans le classpath. Cette fonctionnalité est conçue pour faciliter le développement et est généralement déconseillée en production.

Comme le fichier user.clj est chargé par l'environnement d'exécution Clojure lors de l'initialisation, cela se produit généralement avant l'exécution de l'espace de noms principal de l'application. Par conséquent, tout espace de noms ou ressource chargé par user.clj a un impact sur le temps de démarrage de votre application.

Ajout de bibliothèques pour une utilisation interactive

Dans de nombreux cas de développement, il est utile d'ajouter une bibliothèque de manière interactive sans redémarrer la JVM : évaluation spéculative, ajout d'une dépendance connue à votre projet ou ajout d'une bibliothèque pour accomplir une tâche spécifique.

L'interface de ligne de commande Clojure (CLI) permet de déclarer les dépendances chargées au démarrage du REPL. Depuis Clojure 1.12, vous pouvez également charger dynamiquement des bibliothèques dans le REPL pour une utilisation interactive. Ces fonctions sont disponibles dans l'espace de noms `clojure.repl.deps` :

Fonction Description
add-lib Prend une bibliothèque absente du classpath et la rend disponible en la téléchargeant (si nécessaire) et en l'ajoutant au chargeur de classes. Les bibliothèques déjà présentes dans le classpath ne sont pas mises à jour. Si les coordonnées ne sont pas fournies, la version Maven la plus récente ou l'étiquette Git (si la bibliothèque possède un nom de dépôt Git inféré) est utilisée.
add-libs Est similaire à `add-lib`, mais résout simultanément un ensemble de nouvelles bibliothèques et leurs versions.
sync-deps Appelle add-libs avec toutes les bibliothèques présentes dans deps.edn, mais pas encore présentes dans le classpath.

Ces nouvelles fonctions sont destinées à une utilisation interactive uniquement dans le REPL ; l'utilisation d'un fichier deps.edn reste la méthode appropriée pour construire et maintenir votre code. À cette fin, ces fonctions vérifient toutes que *repl* est lié à true. Dans un REPL clojure.main, ces nouvelles fonctions sont automatiquement référencées dans l'espace de noms utilisateur. Dans d'autres REPL, vous devrez peut-être utiliser la commande (require '[clojure.repl.deps :refer :all]) avant de les utiliser.

tap

tap est un système partagé et accessible globalement permettant de distribuer une série de valeurs d'information ou de diagnostic à un ensemble de fonctions de gestion (présumées actives). Il peut servir de guide de débogage plus performant ou pour des fonctionnalités telles que la journalisation.

La fonction `tap>` envoie une valeur à l'ensemble des points de distribution (`tap`). Des points de distribution peuvent être ajoutés avec `add-tap` et seront appelés avec toute valeur envoyée à `tap>`. La fonction `tap` peut se bloquer brièvement (par exemple, pour les flux) et n'empêchera jamais les appels à `tap>`, mais un blocage indéfini peut entraîner la perte de valeurs. Si aucun point de distribution n'est enregistré, `tap>` ignore la valeur. Supprimez les points de distribution avec `remove-tap`.

Lancement d'un serveur de sockets

L'environnement d'exécution Clojure permet désormais de démarrer un serveur de sockets lors de l'initialisation, en fonction des propriétés système. Cette fonctionnalité est notamment utilisée pour servir un REPL basé sur les sockets, mais elle offre également de nombreuses autres applications potentielles pour ajouter dynamiquement des fonctionnalités serveur à des programmes existants sans modification du code.

Un serveur de sockets sera démarré pour chaque propriété système JVM telle que «clojure.server.<nom-du-serveur>». La valeur de cette propriété est une carte edn représentant la configuration du serveur de sockets avec les propriétés suivantes :

Propriété Description
server-daemon Par défaut, true ; le processus léger du serveur de sockets ne bloque pas la sortie.
address Hôte ou adresse ; par défaut, l'adresse de bouclage.
port Entier positif ; obligatoire.
accept Symbole de la fonction à appeler lors de l'acceptation du socket ; obligatoire.
args Ensemble séquentiel d'arguments à passer à accept.
bind-err Par défaut, true ; lie *err* au flux de sortie du socket.
client-daemon Par défaut, true ; le processus léger du client de sockets ne bloque pas la sortie.

De plus, une fonction REPL légèrement personnalisée pour le serveur de sockets de clojure.core.server/repl est fournie.

Voici un exemple de démarrage d'un serveur de sockets avec un écouteur REPL. Cette fonction peut être ajoutée à n'importe quel programme Clojure existant pour lui permettre d'accepter des clients REPL externes via une connexion locale au port 5555.

  1. -Dclojure.server.repl="{:port 5555 :accept clojure.core.server/repl}"

Avec l'interface de ligne de commande Clojure, utilisez l'option -J pour transmettre l'option à la JVM (notez que cela démarrera également un REPL local en plus du REPL du socket) :

clj -J-Dclojure.server.repl="{:port 5555 :accept clojure.core.server/repl}"

Vous pouvez utiliser par exemple telnet pour vous connecter à ce REPL à distance (vous pouvez également utiliser netcat) :

$ telnet 127.0.0.1 5555
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
user=> (println "hello")
hello

Vous pouvez demander au serveur de fermer la session REPL du client en utilisant la commande spéciale :repl/quit:

user=> :repl/quit
Connection closed by foreign host.

Voir aussi :

Fonctions associées



Dernière mise à jour : Lundi, le 2 février 2026