2011-06-22 56 views
5

Tôi đang cố gắng lấy tài liệu bằng cách sử dụng hàm Clojure doc, nhưng không thể nhận được tài liệu từ REPL (Tôi đang sử dụng Emacs và SLIME). Trình tự sau đây mô tả những gì đang xảy ra (thông báo lỗi sau ngay lập tức sau mỗi dòng):Tại sao REPL xử lý clojure.core/doc dưới dạng 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> 

Làm thế nào để tham khảo các doc chức năng và làm cho nó công nhận là một chức năng, không phải là một biến?


PHỤ LỤC, 6/22/11, 9 giờ sau khi câu hỏi được đăng

@kotarak đưa ra nhận định phù hợp nhất. "Lưu ý, rằng clojure.core/doc là 1.2 và trước đó clojure.repl/doc là 1,3 trở lên. " Chắc chắn, sau đây làm việc:

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> 

tôi đã có thể xác nhận rằng Clojure 1.3 đã hoạt động:

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

Nhưng điều này quá là khó hiểu - project.clj Leiningen tôi đã quy định Clojure 1.2!

Theo kinh nghiệm của riêng tôi, tôi đã từng nhận thấy rằng REPL dựa trên SLIME "treo lên" một giá trị classpath Java ngay cả sau khi tôi đã thay đổi nội dung của các thư mục có liên quan. Giải pháp sau đó là thoát khỏi Emacs và lein swank, sau đó nhập lại và thử lại. Tôi đã thử như vậy và nhận được kết quả sau:

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

Kết luận duy nhất tôi có thể thực hiện là REPL trước đây của tôi đã sử dụng Clojure 1.3. Dự án mà tôi đã làm việc trước đây với số này đã có đã sử dụng ảnh chụp nhanh Clojure 1.3, vì vậy tôi đoán rằng REPL đã "treo lên" Clojure 1.3 bằng cách nào đó.

Vấn đề được giải quyết, bài học kinh nghiệm, vv Đối với điểm thưởng, ai cũng có thể giải thích lý do cho những gì đã xảy ra (với Clojure 1.2 so với 1.3)?

Nhờ tất cả những ai đã đóng góp.

+0

tôi nhận thấy bạn đã không được chấp nhận bất kỳ câu trả lời cho bất kỳ câu hỏi của bạn. Bạn chắc chắn nên chấp nhận một số câu trả lời nếu bạn nghĩ rằng họ là đủ. Đây là cách các trang web stackoverflow hoạt động. – bmillare

+0

@kotarak và @bmillare: Vui lòng đọc câu hỏi của tôi và hai câu trả lời. Tôi nghĩ bạn sẽ đồng ý rằng, mặc dù cả hai câu trả lời đều cố gắng hữu ích, không trả lời câu hỏi của tôi. _Đó là lý do tại sao tôi cũng không chấp nhận. –

+0

@ gregg-williams chắc chắn đúng đối với tất cả các câu hỏi khác của bạn, nơi bạn không cung cấp bất kỳ phản hồi nào cho dù các giải pháp được đề xuất có giúp ích hay không. – kotarak

Trả lời

12

Hai lần sửa chữa. Đầu tiên, doc là macro không phải là hàm. Ngoài ra các hàm và macro có thể được lưu trữ trong một var. Thứ hai, trong clojure 1.3, có khả năng là phiên bản bạn đang sử dụng, doc được lưu trữ trong var clojure.repl/doc, không phải là clojure.core/doc (như trong 1.2). Trong người dùng không gian tên, doc được "sử dụng", hay còn gọi là ẩn "(sử dụng [clojure.repl: only [doc])". Khi bạn goto một không gian tên mới, hoặc thậm chí tạo một với ns, clojure.repl/doc không tự động được thêm vào, không giống như nó là với 'người dùng.

Để rõ ràng hơn về các câu hỏi:

Tại sao REPL điều trị clojure.core/doc như một var?

Chức năng, macro và giá trị trong clojure được lưu trữ trong các vars hoặc bị ràng buộc với một biểu tượng như trong lệnh hoặc chức năng. clojure.core/doc là var chứa macro làm những gì doc làm.

Làm cách nào để tôi tham khảo chức năng của tài liệu và làm cho hàm được nhận dạng dưới dạng hàm chứ không phải biến?

Giống như trong tất cả các lisps, để thực hiện cuộc gọi, cho dù một hàm hay macro, bạn phải đặt hàm/macro vào vị trí đầu tiên của danh sách.

(<fn/macro> *args) 

Vì vậy, để gọi doc vĩ mô về bản thân, bạn sẽ làm gì:

(doc doc) 
+3

Lưu ý rằng 'clojure.core/doc' là 1.2 và trước đó. 'clojure.repl/doc' là 1.3 và mới hơn. – kotarak

1

Các doc cho doc cho thấy nó một macro để mở rộng nó với macroexpand cho thấy là mong đợi tên của một var containging một chức năng. vì vậy câu trả lời rất ngắn cho câu hỏi của bạn sẽ là "các hàm trong một không gian tên được chứa trong các vars".

trong những tình huống như macroexpand-1 này có thể là một nơi tốt để bắt đầu:

(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 
Các vấn đề liên quan