2011-06-22 13 views
5

Próbuję uzyskać dokumentację za pomocą funkcji Clojure doc, ale nie mogę uzyskać rozpoznania z REPL (używam Emacs i SLIME). Poniższa sekwencja opisuje to, co się dzieje (komunikat błędu następuje natychmiast po każdym wierszu):Dlaczego REPL traktuje clojure.core/doc jako 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> 

jaki sposób odnoszą się do funkcji doc i dostać ono rozpoznawane jako funkcji, a nie zmiennej?


aneksu 6/22/11, 9 godzin po pytanie pisał

@kotarak wykonane najistotniejsze. Komentarz: „Uwaga, że ​​clojure.core/doc 1.2 i wcześniejszych clojure.repl/doc to 1.3 i nowsze. " Rzeczywiście, co następuje pracował:

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> 

udało mi się potwierdzić, że Clojure 1.3 był aktywny:

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

Ale to było zbyt skomplikowane - mój Leiningen project.clj nie podano Clojure 1.2!

Z własnego doświadczenia zauważyłem kiedyś, że REPL "oparty na SLIME" "zawiesił" wartość ścieżki klasy Java nawet po zmianie zawartości odpowiednich katalogów. Rozwiązaniem było wtedy wyjście z Emacsa i lein swank, a następnie ponowne wprowadzenie obu i spróbuj ponownie. Próbowałem to samo i mam następujący wynik:

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

Jedyny wniosek mogę sprawić, że mój poprzedni REPL używał Clojure 1.3. Projekt, nad którym pracowałem poprzednio miał wykorzystał migawkę Clojure 1.3, więc domyślam się, że REPL "jakoś wisiał" na Clojure 1.3.

Problem rozwiązany, zdobyta lekcja itp. Czy w przypadku punktów bonusowych ktoś może wyjaśnić przyczynę zdarzenia (z Clojure 1.2 vs. 1.3)?

Dziękuję wszystkim, którzy przyczynili się.

+0

Zauważyłem, że nie przyjęły żadnych odpowiedzi na wszelkie pytania. Powinieneś zdecydowanie przyjąć kilka odpowiedzi, jeśli uważasz, że są wystarczające. Tak działają witryny stackoverflow. – bmillare

+0

@kotarak i @bmillare: przeczytaj moje pytanie i dwie odpowiedzi. Sądzę, że zgodzisz się, że chociaż obie odpowiedzi będą pomocne, nie odpowiadasz na moje pytanie. _ To dlatego nie zaakceptowałem. –

+0

@ gregg-williams, co jest z pewnością prawdziwe również w przypadku wszystkich innych pytań, w których nie przekazano żadnej informacji zwrotnej, czy proponowane rozwiązania pomogły, czy nie. – kotarak

Odpowiedz

12

Kilka poprawek. Po pierwsze dokument to makro, a nie funkcja. Również funkcje i makra można przechowywać w var. Po drugie, w clojure 1.3, która jest prawdopodobnie wersją, której używasz, dokumentacja jest przechowywana w pliku var clojure.repl/doc, a nie clojure.core/doc (tak jak w wersji 1.2). W obszarze użytkownika przestrzeni nazw, dokumentacja jest "używana", inaczej jest "niejawna" (użyj [clojure.repl: only [doc]) ". Kiedy dostajesz nowy obszar nazw, lub nawet tworzysz go z ns, clojure.repl/doc nie jest automatycznie dodawany, w przeciwieństwie do "użytkownika".

Aby być bardziej wyraźne o pytania:

Dlaczego REPL uczta clojure.core/doc jako var?

Funkcje, makra i wartości w clojure są przechowywane w partiach lub powiązane z symbolem, na przykład let lub funkcją. clojure.core/doc jest zmiennym przechowującym makro, które robi to, co robi dokument.

Jak odwołać się do funkcji doc i uzyskać ją jako funkcję, a nie jako zmienną?

Podobnie jak we wszystkich sepsach, aby wykonać połączenie, funkcję lub makro, należy ustawić funkcję/makro na pierwszej pozycji listy.

(<fn/macro> *args) 

Tak, aby wywołać makro doc na sobie, byś zrobił:

(doc doc) 
+3

Pamiętaj, że 'clojure.core/doc' ma wartość 1.2 i wcześniejszą. 'clojure.repl/doc' to 1.3 i nowsze. – kotarak

1

Doc doc pokazuje jego makro tak rozszerzając ją macroexpand wykaże, że spodziewa nazwy var zawierający funkcję. więc bardzo krótka odpowiedź na twoje pytanie brzmi: "funkcje w przestrzeni nazw są zawarte w vars".

w takich sytuacjach macroexpand-1 może być dobrym miejscem do rozpoczęcia:

(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