Самоанализ в Clojure - PullRequest
       10

Самоанализ в Clojure

15 голосов
/ 08 декабря 2011

Какой лучший способ сделать самоанализ в Clojure? Есть ли что-то вроде функции Python dir? Я особенно заинтересован в том, чтобы найти методы, доступные в java-классах, с которыми я взаимодействую, но мне также интересно узнать, что доступно в Clojure, связанное с самоанализом.

Ответы [ 6 ]

15 голосов
/ 08 декабря 2011

Мишель Боркент и Дейв Рэй имеют опции взаимодействия.

Для обнаружения функций 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

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.
-------------------------
....
11 голосов
/ 08 декабря 2011

Если вы используете 1.3, есть clojure.reflect , который позволяет вам просматривать, манипулировать и т. Д. Информацией о классах Java.Мне также нравится clojure.contrib.repl-utils / show из старого Contribu, если это вариант для вас.

10 голосов
/ 08 декабря 2011

Если вы хотите открыть методы, просто используйте простое отражение 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()>,
 ...

Вы также можете написать его немного лучше с помощью макроса потоков:

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

или

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

(я только что узнал из #clojure IRC, что имя самого класса уже является объектом Class!)

3 голосов
/ 22 августа 2014

clojure.contrib.repl-utils перемещено в clojure.reflect.

Теперь вы можете называть это следующим образом:

(->> (clojure.reflect/reflect java.lang.String) 
     :members 
     clojure.pprint/pprint)

https://stackoverflow.com/a/17974908/262425

3 голосов
/ 31 декабря 2013

Чтобы найти интерфейсы, реализованные классом, попробуйте supers

(supers clojure.lang.PersistentHashMap)

3 голосов
/ 08 декабря 2011

Проверьте clojure.contrib.repl-utils и, в частности, show.

http://richhickey.github.com/clojure-contrib/repl-utils-api.html#clojure.contrib.repl-utils/show

Это утилиты для анализа объектов и классов в REPL, но кодхороший пример того, как изучать классы программно.

...