Clojure中的反思

Fra*_*ard 15 introspection clojure

在Clojure中进行内省的最佳方法是什么?是否有类似Python的dir功能?我特别感兴趣的是找到我正在与之互操作的java类上可用的方法,但我也有兴趣找到Clojure中与内省相关的任何东西.

cem*_*ick 15

Michiel Borkent和Dave Ray有互换选项.

为了发现Clojure函数,clojure.repl命名空间中有几个选项(默认情况下可能已经引用了你的REPL).

dir:

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

apropos:

=> (apropos #"^re-")
(re-pattern re-matches re-matcher re-groups re-find re-seq)
Run Code Online (Sandbox Code Playgroud)

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.
-------------------------
....
Run Code Online (Sandbox Code Playgroud)


Dav*_*Ray 11

如果您使用的是1.3,则可以使用clojure.reflect来检查,操作等有关Java类的信息.我也喜欢旧的contrib 的clojure.contrib.repl-utils/show,如果这是你的选择.


Mic*_*ent 10

如果要发现方法,只需使用普通的Java反射:

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()>,
 ...
Run Code Online (Sandbox Code Playgroud)

您还可以使用线程宏更好地编写它:

(-> {:a 1} .getClass .getDeclaredMethods pprint)
Run Code Online (Sandbox Code Playgroud)

要么

(-> clojure.lang.PersistentArrayMap .getDeclaredMethods pprint)
Run Code Online (Sandbox Code Playgroud)

(我刚从#clojure IRC那里学到了类本身的名称已经是Class对象!)