Ich bin gerade dabei, einer vorhandenen J2EE-Webanwendung Funktionalität in einem Tomcat-Container hinzuzufügen, und ich schreibe meine Ergänzungen mit Clojure. Meine Einrichtung ist einfach: Ich füge nur Aufrufe zu statischen Methoden hinzu, die von clojure generiert wurden, und schreibe die ganze harte Arbeit von der Clojure-Seite aus. Der Build-Prozess besteht darin, clojure code (lein uberjar
) zu kompilieren und dann den Java-Code mit diesem jar auf dem Klassenpfad zu kompilieren.Wie verbinde ich eine Clojure-Quelldatei mit einer laufenden Clojure-Replik auf Emacs?
In der Webapp-Init habe ich einen Aufruf an eine generierte Klasse, die einen Swank-Server mit einem (swank/start-repl)
startet. Ich möchte in der Lage sein, den Schleim meiner Aquamacs mit diesem Server zu verbinden und interaktiv von dort zu arbeiten (bis zu einem gewissen Punkt werde ich nichts versuchen, was eine Neukompilierung auf der Java-Seite erfordert). Aber ich habe eine Situation, die ich nicht ganz verstehe. Wenn ich eine \M-x slime-connect
mache, bekomme ich eine REPL-Eingabeaufforderung (nachdem ich benachrichtigt wurde, dass es keinen minderwertigen Lisp-Prozess gibt, was meiner Meinung nach in Ordnung ist, da der untergeordnete Lisp-Prozess außerhalb von Emacs-Kontrolle läuft). Ich kann Formulare perfekt auswerten, und ich kann sogar Dinge wie my.own.namespace/my-var
untersuchen. Wenn ich jedoch eine Datei mit einem bereits kompilierten Clojure-Code besuche, kann ich den Schleim nicht als Quelle erkennen lassen. Betrachten wir ein einfaches clojure Datei:
(ns my.namespace
(:gen-class
:name my.namespace
:methods [#^{:static true} [testFunc [] void]]))
(def *secret* "shhhh")
(defn -testFunc []
(println (str "our secret is: " secret)))
Unter der Annahme, dass dies in der uberjar durch die Webapp geladen zusammengestellt und enthalten ist, kann ich eval/inspizieren my.namespace/*secret*
. Aber wenn ich versuche, innerhalb des Codepuffers auszuprobieren, denkt Slime, dass ich auf dem Namespace user
bin (was sogar Sinn machen kann!). Aber jetzt habe ich noch eine einzige Arbeitsmöglichkeit - ich muss alle Formulare in der Datei nacheinander auswerten! \C-c \C-l
(Laden der Quelldatei) wird nichts tun - scheinbar nur NULL zurückgibt und sonst nichts ausgibt. Alles kompilieren scheint genau das zu tun - es kompiliert, zeigt Fehler an, wenn es sie findet, ändert aber meinen Namensraum nicht. Und das Seltsamste ist das \C-~
(Sync Paket und Verzeichnis), das mit Common Lisp genau das macht, was ich will, aber hier friert es die Clojure REPL für immer ein.
Es gibt immer die Möglichkeit, zu der REPL zu wechseln, indem Sie (in-ns 'my.namespace)
eingeben, und dann funktioniert alles ordnungsgemäß. Aber das ist einfach nicht praktisch genug, wenn die Clojure-Dateien an Zahl zunehmen (da der Namespace des Code-Puffers sich nicht automatisch ändert!)
Meine Frage ist also, ob mir ein Grundbefehl fehlt/Konfiguration - oder wenn es einen offensichtlichen Grund dafür gibt, dass dieses Verhalten als solches auftritt.
Zitieren der Frage: "Kompilieren alles scheint genau das zu tun" - was meinst du? Das heißt, auf welche Methode des Ladens von Clojure-Code beziehen Sie sich, wenn Sie "alles kompilieren" sagen (Clojure-Code wird immer kompiliert, aber Sie haben wahrscheinlich einige SLIME-Funktion im Hinterkopf). Und welches Ergebnis erwarten Sie genau? –
"Alles kompilieren" - "Cc Ck" wird alle Formulare im Puffer der Datei auf Emacs kompilieren, Fehler auf diesen Formularen darstellen und effektiv neu definierte (und neu definierte) Formulare dynamisch verfügbar machen (zB wird ein Webapp-Aufruf verwendet) dieser neu kompilierte Code). Entschuldige, dass ich nicht so klar bin wie ich. – Edgar
Ich erwartete ein ähnliches Verhalten wie beim Starten von SLIME mit 'Mx swank-clojure-project': Beim Wechsel in den Puffer einer Datei wird der Namespace automatisch geändert, also wird der Namespace' user' nicht ausgewertet . Alternativ sollte beim Kompilieren/Laden des Puffers unter Verwendung von "C-c C-k"/"C-c C-l" alle Formen ausgewertet werden, einschließlich des anfänglichen "(ns ...)", wodurch zu einem bestimmten Namensraum gewechselt wird und alle nachfolgenden Variablen dazu gehören. Ist das nicht das erwartete Verhalten in einer Standardkonfiguration? (Ich könnte es in die falsche Richtung sehen ...) – Edgar