2011-12-08 25 views
15

¿Cuál es la mejor manera de hacer introspección en Clojure? ¿Hay algo así como la función dir de Python? Estoy particularmente interesado en encontrar los métodos que están disponibles en las clases de Java con los que estoy interoperando, pero también estoy interesado en descubrir cualquier cosa que esté disponible en Clojure relacionada con la introspección.Introspección en Clojure

+1

Tal clojure.reflect es vale la pena analizar también. http://clojure.github.io/clojure/clojure.reflect-api.html – claj

Respuesta

10

Si quieres descubrir métodos, sólo tiene que utilizar llanura de Java reflexión:

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()>, 
... 

También puede escribir un poco más agradable con una macro rosca:

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

o

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

(¡Acabo de enterarme de #clojure IRC que el nombre de la clase en sí ya es el objeto Class!)

+0

'(.getDeclaredMethods (clase {: a 1}))' funciona, también. – Mars

11

Si está utilizando 1.3, hay clojure.reflect que le permite inspeccionar, manipular, etc. información sobre las clases de Java. También me gusta el clojure.contrib.repl-utils/show del contrib anterior si esa es una opción para ti.

15

Michiel Borkent y Dave Ray tienen las opciones de interoperabilidad cubiertas.

Para descubrir las funciones de Clojure, hay un par de opciones en el espacio de nombres clojure.repl (que probablemente ya se mencionen en su REPL por defecto).

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

Para encontrar interfaces implementadas por una clase, intentan supers

(supers clojure.lang.PersistentHashMap)