【问题标题】:Introspection in ClojureClojure 中的自省
【发布时间】:2011-12-08 18:09:14
【问题描述】:

在 Clojure 中进行自省的最佳方式是什么?有没有类似 Python 的 dir 函数的东西?我对查找与我交互操作的 java 类上可用的方法特别感兴趣,但我也有兴趣找出 Clojure 中与自省相关的任何可用方法。

【问题讨论】:

标签: clojure introspection


【解决方案1】:

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

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.
-------------------------
....

【讨论】:

    【解决方案2】:

    如果你想发现方法,只需使用普通的 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】:

      如果您使用的是 1.3,则有 clojure.reflect,它允许您检查、操作等有关 Java 类的信息。如果您可以选择的话,我也很喜欢来自 old contrib 的 clojure.contrib.repl-utils/show

      【讨论】:

        【解决方案4】:

        查看clojure.contrib.repl-utils,尤其是show

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

        这些是用于自省 REPL 中的对象和类的实用程序,但代码是如何以编程方式探索类的一个很好的示例。

        【讨论】:

          【解决方案5】:

          要查找类实现的接口,请尝试supers

          (supers clojure.lang.PersistentHashMap)

          【讨论】:

            【解决方案6】:

            clojure.contrib.repl-utils 已移至 clojure.reflect

            你现在可以这样称呼它:

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

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2023-04-06
              • 1970-01-01
              • 2017-07-18
              • 1970-01-01
              • 1970-01-01
              • 2018-09-30
              • 2012-10-31
              • 1970-01-01
              相关资源
              最近更新 更多