2011-12-08 5 views
15

Cách tốt nhất để làm nội tâm trong Clojure là gì? Có chức năng nào giống như chức năng dir của Python không? Tôi đặc biệt quan tâm đến việc tìm kiếm các phương thức có sẵn trên các lớp java mà tôi đang tương tác với, nhưng tôi cũng quan tâm đến việc tìm ra bất kỳ thứ gì có sẵn trong Clojure liên quan đến sự mẫn cảm.Introspection ở Clojure

+1

lẽ clojure.reflect là giá trị xem xét là tốt. http://clojure.github.io/clojure/clojure.reflect-api.html – claj

Trả lời

10

Nếu bạn muốn khám phá phương pháp, chỉ cần sử dụng đồng bằng Java phản ánh:

user=> (.getDeclaredMethods (.getClass {:a 1})) 
#<Method[] [Ljava.lang.reflect.Method;@72b398da> 
user=> (pprint *1) 
[#<Method private int clojure.lang.PersistentArrayMap.indexOf(java.lang.Object)>, 
#<Method public int clojure.lang.PersistentArrayMap.count()>, 
#<Method public java.util.Iterator clojure.lang.PersistentArrayMap.iterator()>, 
#<Method public boolean clojure.lang.PersistentArrayMap.containsKey(java.lang.Object)>, 
#<Method public int clojure.lang.PersistentArrayMap.capacity()>, 
#<Method public clojure.lang.IPersistentMap clojure.lang.PersistentArrayMap.empty()>, 
... 

Bạn cũng có thể viết nó một chút đẹp hơn với một macro luồng:

(-> {:a 1} .getClass .getDeclaredMethods pprint) 

hoặc

(-> clojure.lang.PersistentArrayMap .getDeclaredMethods pprint) 

(Tôi vừa học được từ #clojure IRC rằng tên của chính lớp đó đã là đối tượng Lớp!)

+0

'(.getDeclaredMethods (class {: a 1}))' cũng hoạt động. – Mars

11

Nếu bạn đang sử dụng 1,3, có clojure.reflect cho phép bạn kiểm tra, thao tác, v.v. thông tin về các lớp Java. Tôi cũng thích số clojure.contrib.repl-utils/show từ thư mục cũ nếu đó là tùy chọn cho bạn.

15

Michiel Borkent và Dave Ray có các tùy chọn interop được đề cập.

Để khám phá các chức năng Clojure, có một vài tùy chọn trong không gian tên clojure.repl (có thể đã được nhắc đến REPL của bạn theo mặc định).

dir:

=> (require 'clojure.set) 
nil 
=> (dir clojure.set) 
difference 
index 
intersection 
join 
map-invert 
project 
rename 
rename-keys 
select 
subset? 
superset? 
union 

apropos:

=> (apropos #"^re-") 
(re-pattern re-matches re-matcher re-groups re-find re-seq) 

find-doc:

=> (find-doC#"^re-") 
------------------------- 
clojure.core/re-find 
([m] [re s]) 
    Returns the next regex match, if any, of string to pattern, using 
    java.util.regex.Matcher.find(). Uses re-groups to return the 
    groups. 
------------------------- 
clojure.core/re-groups 
([m]) 
    Returns the groups from the most recent match/find. If there are no 
    nested groups, returns a string of the entire match. If there are 
    nested groups, returns a vector of the groups, the first element 
    being the entire match. 
------------------------- 
.... 
3

Để tìm giao diện được thực hiện bởi một lớp, hãy thử supers

(supers clojure.lang.PersistentHashMap)