2010-08-12 9 views
5

Actualmente estoy en el proceso de agregar funcionalidad a una aplicación web J2EE existentes, en un contenedor Tomcat, y estoy escribiendo mis adiciones utilizando Clojure. Mi configuración es simple: simplemente agrego llamadas a métodos estáticos generados por clojure, y codigo todo el trabajo duro desde el lado de Clojure. El proceso de compilación consiste en compilar el código de clojure (lein uberjar) y luego compilar el código java con ese jar en el classpath.¿Cómo conecto un archivo fuente de clojure a un clojure repl en ejecución en Emacs?

En el init webapp, tengo una llamada a una clase generada que dispara un servidor ostentoso con un (swank/start-repl). Me gustaría poder conectar el fango de mi Aquamacs a ese servidor, y trabajar de forma interactiva desde allí (hasta cierto punto, no intentaré nada que requiera una recompilación del lado de Java). Pero tengo una situación que no entiendo del todo. Si hago un \M-x slime-connect, aparece un indicador de REPL (después de haber sido notificado de que no hay ningún proceso de Lisp inferior, que creo que está bien, ya que el proceso Lisp inferior está funcionando fuera de control emacs). Puedo evaluar formularios perfectamente, e incluso puedo inspeccionar cosas como my.own.namespace/my-var. Sin embargo, si visito un archivo con un código clojure ya compilado, no puedo hacer que limo lo reconozca como su fuente. Considere un simple archivo de clojure:

(ns my.namespace 
    (:gen-class 
    :name my.namespace 
    :methods [#^{:static true} [testFunc [] void]])) 

(def *secret* "shhhh") 

(defn -testFunc [] 
    (println (str "our secret is: " secret))) 

Suponiendo que esto se compila y se incluye en el uberjar cargado por la aplicación de web, puedo eval/inspeccionar my.namespace/*secret*. Pero si trato de evaluar dentro del búfer de código, Slime piensa que estoy en el espacio de nombres user (¡que incluso puede tener sentido!). Pero ahora me queda una sola opción de trabajo, tengo que evaluar, ¡uno por uno, todos los formularios en el archivo! \C-c \C-l (cargar el archivo de origen) no hará nada, aparentemente solo devuelve nada y no genera nada más. Compilar todo parece hacer precisamente eso: compila, muestra errores si los encuentra, pero no cambiará mi espacio de nombres. Y lo más extraño es el \C-~ (paquete y directorio de sincronización), que utilizando Common Lisp hace exactamente lo que yo quiero, pero aquí congela el clojure REPL para siempre.

Siempre existe la opción de cambiar a la REPL, escribiendo (in-ns 'my.namespace), y luego todo funciona correctamente. Pero eso simplemente no es lo suficientemente práctico cuando los archivos clojure están creciendo en número (¡ya que el espacio de nombres del buffer del código no cambiará automáticamente!)

Mi pregunta es, entonces, si me falta un comando básico/configuración - o si hay una razón obvia para que este comportamiento ocurra como tal.

+0

Citando la pregunta: "Compilar todo parece hacer exactamente eso", ¿qué quieres decir? Es decir, a qué método de carga del código de Clojure se refiere cuando dice "compilar todo" (el código de Clojure siempre se compila, pero es probable que tenga alguna función SLIME en mente). Además, ¿qué resultado, exactamente, esperas? –

+0

"Compilando todo" - presionando 'Cc Ck' compilará todos los formularios en el búfer del archivo en emacs, presentando errores en esos formularios, y haciendo que los formularios redefinidos (y recientemente definidos) estén disponibles dinámicamente (por ejemplo, una llamada de webapp estará usando este código recién compilado). Perdón por no ser tan claro como pude. – Edgar

+0

Estaba esperando un comportamiento similar al que presento al iniciar SLIME con 'Mx swank-clojure-project': al cambiar al buffer de un archivo, el espacio de nombres cambia automáticamente, por lo que evaluar algo no usará el espacio de nombres' user' . Alternativamente, al compilar/cargar el buffer usando 'C-c C-k' /' C-c C-l' debería evaluar todas las formas, incluyendo el '(ns ...)' inicial, cambiando así a un espacio de nombres específico y haciendo que todas las variables subsecuentes le pertenezcan. ¿No es este el comportamiento esperado en una configuración estándar? (Podría estar mirando de la manera incorrecta ...) – Edgar

Respuesta

1

Acabo de descubrir que eliminando el culpable de este problema: slime-redirect-inferior-output, de slime-repl.el, estaba siendo llamado desde un gancho que tenía configurado. Resulta que no funciona bien sin un proceso de lisp inferior (léase, un servidor swank comenzó desde dentro de emacs).

Así que un hack solución rápida es sólo para eliminar la forma error de esa función, como this. Ahora el gancho procede y los espacios de nombres se calculan automáticamente. Como era la intención. Gracias por las sugerencias, sin embargo, ¡me llevaron a esta solución!

5

Es posible que esté malinterpretando su problema, pero no puede (al visitar este búfer hipotético en emacs), pulse C-c C-k para compilar el búfer en su instancia Clojure actual (¿a qué Slime está conectado)?

Luego, en el buffer de limo, cambiar a este espacio de nombres con un (in-ns 'my.namespace). Entonces debería tener acceso a lo que compiló en ese espacio de nombres.

+0

Hmm, como he escrito en el comentario de una pregunta, esa compilación funcionará, pero mi punto es que estoy acostumbrado a eso '(in-ns 'my .namespace) 'para estar implícito después de un compile/load-file. Funcionó de esta manera en todas las implementaciones de Common Lisp que he usado con SLIME, IIRC; Además, tener que cambiar los espacios de nombres manualmente en un proyecto de 10 o más archivos (especialmente con reinicios de clojure más que deseables) lleva a la fatiga, y poco después, a la locura :), así que si no estoy haciendo algo mal y la interacción Supongo que es así, ¡codificaré una solución alternativa! – Edgar

+0

Ah, también, el '(in-ns 'my.namespace)' no funciona en absoluto si se evalúa en su lugar, en el búfer de archivo .clj - Tengo que hacerlo en el REPL, luego el búfer de ese archivo cambia su espacio de nombres Eso también es menos que obvio, para mí. – Edgar

+0

Tienes toda la razón, es un dolor en el culo. Me acabo de acostumbrar, supongo, y no había codificado w/Slime/Swank antes de Clojure. ¡Avíseme si consigue trabajo! Supongo que las cosas te están funcionando ahora. ¿Hay algo todavía sin respuesta? (¡No es que haya respondido nada, pero me gustaría saber si aún puedo ayudar!) – Isaac

2

espacios de nombres cambiando automáticamente en la compilación no ha sido nunca el valor predeterminado para Swank-clojure, aunque podría ser una característica opcional de baba que le pasó a trabajar con Clojure. Pero C-c M-p para cambiar la réplica al espacio de nombres del búfer actual siempre me ha funcionado, y nunca he escuchado que alguien tenga problemas con él.

¿Está ejecutando en las últimas versiones estables de clojure-mode y limo-repl? ¿Tienes instalado swank-clojure.el? (No debería necesitarlo). Parece que esto podría deberse a versiones no coincidentes de las libs elisp. Si ese no es el problema, podría ser un error de Aquamacs; swank-clojure está diseñado para trabajar con GNU Emacs. También podría ser un error en la baba si está ejecutando desde el tronco en lugar de la última versión de elpa.

+1

Me di cuenta hace un par de horas que 'C-c M-p' funcionó perfectamente en mi configuración (Aquamacs, la última versión estable de clojure-mode y slime-repl, clojure-1.2-rc1).Lo que sigue colgando es 'C-c ~', pero supongo que el comando SLIME solo funciona para las implementaciones de Common Lisp. Lo que esperaba era hacer un 'C-c C-l' (cargar) en un archivo. Esperaba que el espacio de nombres cambiara, pero no lo hará. Solo para beneficio de futuros lectores, la función que esbocé en http://gist.github.com/522706 también funciona, pero no solicita un espacio de nombres, lo adivina desde el primer '(ns ...) 'forma en el buffer. – Edgar