47 votes

Meilleures pratiques pour la construction et le déploiement d'applications Clojure: de bons tutoriels?

Je suis nouveau sur Clojure, et je commence à expérimenter avec la construction d'une application.

Jusqu'à présent, tout ce que j'ai vu sur des tutoriels sur la compilation de Clojure programmes implique l'interactivité. Par exemple, "charger le REPL et le type (load-file "ceci-ou-que") pour fonctionner. Ce qui est bien, mais ça ne suffit pas.

Je suis tellement habituée à l'édition-compilation-exécution des idiomes de langages tels que le C ou Delphi, que je suis instinctivement conduits à faire des modifications, puis appuyez sur "M-x compile".

Le problème est que "lein uberjar", je crois comprendre que c'est l'équivalent de "faire", est très lente à exécuter, même pour un hello world. Donc je vais avoir à comprendre comment ce "développement interactif" substance fonctionne, arrêtez d'utiliser le uberjar comme c'est rapide à faire, et l'enregistrer uniquement pour la fin de la journée.

Une autre chose que j'ai remarqué lors de la construction (à l'aide de lein uberjar), c'est que le petit GUI application que je suis en train de travailler sur les pop-up cadres dans le processus de compilation, comme si ils sont d'exécution lors de la compilation. Il semble un peu contre-intuitif pour moi; il n'est pas tout à fait comme analogue à "faire" comme je l'avais pensé.

Je sais que le Lisp façon de développer des choses est de manière interactive de travail dans le REPL, et je ne suis pas en train de changer cela: je voudrais adapter à ce mode de vie. Malheureusement, j'ai vu très peu dans la forme de la documentation sur la façon de le faire. Par exemple, comment faire pour réinitialiser l'état actuel de la machine. Il semble tout genre bordélique pour garder juste la compilation individu extraits de code à la volée, sans être en mesure de faire une sorte de reset.

La plupart des tutos que j'ai vu sur Clojure (et Lisp) en général semblent se concentrer sur le piratage dans le REPL. Les meilleures pratiques pour le déploiement des applications reste un mystère pour moi. Mes utilisateurs sont simplement des utilisateurs; ils ne sont pas les développeurs qui vont charger des fichiers dans un REPL.

Voici donc ma question: toutes les ressources pour la bonne information ou de tutoriels sur l'ensemble du processus de construction d'une Clojure application, y compris le déploiement?

(Note: j'ai toutes les conditions requises installé et de travail (par exemple Emacs, Slime, Leiningen, etc.), ce n'est donc pas une question à ce sujet).

26voto

Michał Marczyk Points 54179

Un couple de conseils, puis quelques liens:

Ne pas utiliser lein uberjar au cours du développement; préférez lein jar. La différence est que, lein uberjar met tous vos dépendances dans le générés jar (y compris Clojure lui-même), de sorte que votre pot est entièrement autonome package de votre application à l'intérieur; lein jar seulement des pots de votre propre code. L' uberjar approche a des avantages évidents pour le déploiement, mais pour le développement, vous devriez être en mesure de simplement utiliser le classpath lors de l'exécution de votre application, vous sauver du temps nécessaire pour préparer un uberjar. Si vous ne voulez pas à la main-gérer le classpath pour un test, découvrez l' lein run plugin.

Aussi, le plus susceptible de la majorité de votre code ne devrait pas être AOT compilé. AOT est nécessaire dans certains Java interop scénarios, mais la plupart du temps, il apporte un léger boost en vitesse de démarrage et ennuyeux problèmes avec la compatibilité binaire avec les différentes versions de Clojure. Je suppose que cette dernière question n'est pas pertinente pour un uberjar-ed application autonome type de projet, mais une bibliothèque de code devrait au moins être de gauche pour être JIT-ed si possible. Avec Leiningen, vous pouvez mettre un :namespaces clause dans l' defproject formulaire en project.clj pour déterminer les espaces de noms doivent être compilés; tout ce que vous laissez de côté permettra d'être actuellement JIT-ed par défaut. Les anciennes versions de Leiningen utilisé pour compiler le tout par défaut, qui est en fait une bonne raison de passer!

Comme pour les fenêtres d'éclater lors de la compilation, je suppose que vous êtes soit en cours d'exécution fenêtre-out-popping code pendant la macro-expansion moment ou en dehors de toute définition de la fonction ou similaire construire. (Quelque chose comme un (println "Foo!") au niveau supérieur.) C'est juste quelque chose que vous ne devriez pas faire, je suppose, à moins que vous envisagez d'exécuter votre code d'un script, de toute façon. Pour éviter le problème, enveloppez-côte-d'effectuer code dans les définitions de fonctions et de fournir un point d'entrée de votre application à l'aide de l' :main clause en project.clj. (Si vous dites :main foo, puis l' -main fonction de l' foo de l'espace de noms sera utilisé comme point d'entrée de votre application. C'est la valeur par défaut, de toute façon, et au moins le ci-dessus mentionné lein run semble avoir le nom codé en dur -- ce n'est pas sûr lein lui-même.)

Comme pour la réinitialisation de l'état de la REPL-vous pouvez juste redémarrer. Avec la boue, M-x micro-redémarrer-inférieure-lisp va le faire tout en conservant tous les autres de l'état de votre session Emacs.

Voir aussi ces discussions sur la Clojure groupe Google:

  1. Clojure pour l'administration du système
  2. Préparer clojure pour l'emballage (était: Re: Clojure pour l'administration du système)
  3. Leiningen, Clojure et les bibliothèques: ce qui me manque?

13voto

Svante Points 24355

Non, vous n'avez pas à entrer des fonctions sur le REPL.

Vous modifiez vos fichiers source, comme d'habitude. Le Lisp avantage est que vous avez le système en cours d'exécution en arrière-plan, dans le même temps, de sorte que vous pouvez compiler les différentes fonctions de votre fichier source et de les mettre dans le système en cours d'exécution, ou même se substituer à eux.

Si vous utilisez la boue, vous appuyez sur C-c C-c de votre fichier source pour compiler et charger la fonction au point. Vous pouvez ensuite passer à la REPL pour tester et explorer, mais tout ce que vous voulez persister en tant que source, que vous mettez dans vos fichiers source.

Tutoriels commencent généralement en tapant des choses sur le REPL, car il n'y a pas beaucoup que vous devez mettre en place, mais grave, de développement intègre le système en cours d'exécution et source de gestion de fichiers.


Juste pour illustrer, mon habitude de flux de travail (je suis aide Common Lisp, mais Clojure est similaire) est comme ceci:

  • Début Emacs
  • M-x slime pour démarrer la boue, le système Lisp, et de relier les deux par Swank
  • , (commande) load-system foo à la charge du projet en cours (compilation seulement si nécessaire) dans l'image
  • C-x b passer à un tampon source
  • C-c ~ faire le répertoire source dans le répertoire courant et le paquet source du paquet actuel de la REPL

Maintenant, je suis mis avec mon système en cours d'exécution en arrière-plan. De travail est alors:

  • modifier ou ajouter une fonction ou d'une définition de classe
  • C-c C-c de compiler et de le charger dans l'image
  • interrupteur à REPL, test
  • debug

Il n'y a pas importante compilation s'arrête, parce que je n'ai jamais compiler le tout à la fois, ses propres définitions.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X