2011-06-22 7 views
5

Estoy tratando de obtener la documentación mediante la función de Clojure doc, pero no puede lograr que se reconoció desde el REPL (estoy usando Emacs y el asfalto). La siguiente secuencia describe lo que está pasando (mensaje de error sigue inmediatamente después de cada línea):¿Por qué REPL trata a clojure.core/doc como una var?

gaidica.core> (doc first) 
; Evaluation aborted. 

Unable to resolve symbol: doc in this context 
    [Thrown class java.lang.Exception] 

gaidica.core> (clojure.core/doc first) 
; Evaluation aborted. 

No such var: clojure.core/doc 
    [Thrown class java.lang.Exception] 

user> (clojure.core/doc first) 
; Evaluation aborted. 

No such var: clojure.core/doc 
    [Thrown class java.lang.Exception] 

user> (doc first) 
------------------------- 
clojure.core/first 
([coll]) 
    Returns the first item in the collection. Calls seq on its 
    argument. If coll is nil, returns nil. 
nil 
user> 

¿Cómo se refieren a la función doc y lograr que se reconoce como una función, no una variable?


ADENDA, 6/22/11, 9 horas después de la pregunta publicada

@kotarak hizo el comentario más relevante: ". Tenga en cuenta, que clojure.core/doc es de 1.2 y anteriores clojure.repl/doc es 1.3 y más tarde ". Efectivamente, los siguientes trabajó:

user> (clojure.repl/doc first) 
------------------------- 
clojure.core/first 
([coll]) 
    Returns the first item in the collection. Calls seq on its 
    argument. If coll is nil, returns nil. 
nil 
user> 

pude confirmar que Clojure 1.3 fue activo:

user> *clojure-version* 
{:interim true, :major 1, :minor 3, :incremental 0, :qualifier "master"} 
user> 

Pero esto también era confuso - mi project.clj Leiningen había especificado Clojure 1.2!

En mi propia experiencia, una vez que se dio cuenta de que el REPL basada en BABA "se colgó de" un valor ruta de clases de Java, incluso después de cambiar el contenido de directorios relevantes. La solución entonces era salir de Emacs y lein swank, luego volver a ingresar ambos e intentar nuevamente. Probé la misma y dieron el siguiente resultado:

user> *clojure-version* 
{:major 1, :minor 2, :incremental 0, :qualifier ""} 
user> 

La única conclusión que puedo hacer es que mi anterior REPL había estado utilizando Clojure 1.3. El proyecto en el que trabajé anterior a esta tenía utilizó un Clojure 1.3 instantánea, así que supongo que el REPL tenido "colgado en" Clojure 1.3 de alguna manera.

Problema resuelto, lección aprendida, etc. Para los puntos de bonificación, ¿alguien puede explicar la razón por lo que pasó (con Clojure 1.2 vs. 1.3)?

Gracias a todos los que contribuyeron.

+0

me di cuenta de que no ha aceptado ninguna respuesta a cualquiera de sus preguntas. Definitivamente debe aceptar algunas respuestas si cree que son suficientes. Así es como funcionan los sitios web stackoverflow. – bmillare

+0

@kotarak y @bmillare: Por favor, lea mi pregunta y las dos respuestas. Creo que estarás de acuerdo en que, aunque ambas respuestas intentan ser útiles, ninguna responde mi pregunta. Esa es la razón por la que tampoco acepté. –

+0

@ gregg-williams, que es cierto también para todas sus otras preguntas, en las que no proporcionó comentarios sobre si las soluciones propuestas ayudaron o no. – kotarak

Respuesta

12

Par de correcciones. Primero, doc es una macro no una función. También se pueden almacenar funciones y macros en una var. En segundo lugar, en clojure 1.3, que es probablemente la versión que está utilizando, doc se almacena en var clojure.repl/doc, no en clojure.core/doc (como en 1.2). En el usuario del espacio de nombres, doc es "usado", también conocido como "implícito" (use [clojure.repl: only [doc]) ". Cuando ingresa un nuevo espacio de nombres, o incluso crea uno con ns, clojure.repl/doc no se agrega automáticamente, a diferencia de lo que ocurre con 'user'.

Para ser más explícito acerca de las preguntas:

¿Por qué tratar REPL clojure.core/doc como un var?

Las funciones, macros y valores en clojure se almacenan en vars o se enlazan a un símbolo como en una función let o. clojure.core/doc es la var que contiene la macro que hace lo que hace el documento.

¿Cómo me refiero a la función doc y la reconozco como una función, no como una variable?

Como en todos los ceses, para hacer una llamada, ya sea una función o una macro, debe poner la función/macro en la primera posición de una lista.

(<fn/macro> *args) 

Así que llamar al doctor macro en sí misma, puede hacer:

(doc doc) 
+3

Tenga en cuenta que 'clojure.core/doc' es 1.2 y anterior. 'clojure.repl/doc' es 1.3 y posterior. – kotarak

1

El doc para doc muestra es una macro para expandirlo con macroexpand, vemos que se esperando el nombre de un var containging a una función. por lo que la respuesta muy breve a su pregunta sería "las funciones en un espacio de nombres están contenidas en vars".

en situaciones como esta macroexpand-1 puede ser un buen punto de partida:

(macroexpand-1 '(doc doc)) 
(clojure.core/print-doc (var doc)) 
sso-config.core> (doc doc) 
------------------------- 
clojure.core/doc 
([name]) 
Macro 
    Prints documentation for a var or special form given its name 
Cuestiones relacionadas