2014-08-30 72 views
4

我使用Clojure和Java互操作性玩Java方法和我想出了以下檢查一些實例的方法:如何探索通過REPL

(defn methods-of [instance & [string]] 
    {:pre [(nil? instance)]} 
    (filter #(re-find (re-pattern (or string #".*")) %) (map #(.getName %) (-> instance class .getMethods)))) 

但我想知道,因爲這是一個非常實用的方式從REPL獲取這些信息,如果有一些圖書館可以實現這一目標(以及更多)。

+0

我知道這是一個emacs插件。 – Anoop 2014-08-30 15:02:12

+0

哪一個?如果可能的話,移植它會很好。它不應該很難。 – 2014-08-30 15:08:18

+0

http://www.braveclojure.com/using-emacs-with-clojure/。 。這個鏈接我在網上找到。我不確定它是哪一個。我見過一個人在聚會上使用它。 – Anoop 2014-08-30 15:14:48

回答

7

Clojure帶有一個幫助反射的名稱空間:clojure.reflect。使用的主要功能是clojure.reflect/reflect。

user> (require '[clojure.reflect :as reflect]) 
nil 
user> (clojure.pprint/pprint (reflect/reflect (java.util.Date.))) 
{:bases 
#{java.io.Serializable java.lang.Comparable java.lang.Object 
    java.lang.Cloneable}, 
:flags #{:public}, 
:members 
#{{:name getSeconds, 
    :return-type int, 
    :declaring-class java.util.Date, 
    :parameter-types [], 
    :exception-types [], 
    :flags #{:public}} 
    {:name serialVersionUID, 
    :type long, 
    :declaring-class java.util.Date, 
    :flags #{:private :static :final}} 
    {:name getCalendarDate, 
    :return-type sun.util.calendar.BaseCalendar$Date, 
    :declaring-class java.util.Date, 
    :parameter-types [], 
    :exception-types [], 
    :flags #{:private :final}} 
    {:name after, 
    :return-type boolean, 
    :declaring-class java.util.Date, 
    :parameter-types [java.util.Date], 
    :exception-types [], 
    :flags #{:public}} 
    {:name hashCode, 
    :return-type int, 
    :declaring-class java.util.Date, 
    :parameter-types [], 
    :exception-types [], 
    :flags #{:public}} 
    {:name wtb, 
    :type java.lang.String<>, 
    :declaring-class java.util.Date, 
    :flags #{:private :static :final}} 
    {:name setMonth, 
    :return-type void, 
    :declaring-class java.util.Date, 
    :parameter-types [int], 
    :exception-types [], 
    :flags #{:public}} 
    {:name getMonth, 
    :return-type int, 
    :declaring-class java.util.Date, 
    :parameter-types [], 
    :exception-types [], 
    :flags #{:public}} 
    {:name getCalendarSystem, 
    :return-type sun.util.calendar.BaseCalendar, 
    :declaring-class java.util.Date, 
    :parameter-types [int], 
    :exception-types [], 
    :flags #{:private :static :final}} 
    {:name fastTime, 
    :type long, 
    :declaring-class java.util.Date, 
    :flags #{:transient :private}} 
    {:name defaultCenturyStart, 
    :type int, 
    :declaring-class java.util.Date, 
    :flags #{:private :static}} 
    {:name writeObject, 
    :return-type void, 
    :declaring-class java.util.Date, 
    :parameter-types [java.io.ObjectOutputStream], 
    :exception-types [java.io.IOException], 
    :flags #{:private}} 
    {:name getMillisOf, 
    :return-type long, 
    :declaring-class java.util.Date, 
    :parameter-types [java.util.Date], 
    :exception-types [], 
    :flags #{:static :final}} 
    {:name getMinutes, 
    :return-type int, 
    :declaring-class java.util.Date, 
    :parameter-types [], 
    :exception-types [], 
    :flags #{:public}} 
    {:name ttb, 
    :type int<>, 
    :declaring-class java.util.Date, 
    :flags #{:private :static :final}} 
    {:name setDate, 
    :return-type void, 
    :declaring-class java.util.Date, 
    :parameter-types [int], 
    :exception-types [], 
    :flags #{:public}} 
    {:name setSeconds, 
    :return-type void, 
    :declaring-class java.util.Date, 
    :parameter-types [int], 
    :exception-types [], 
    :flags #{:public}} 
    {:name java.util.Date, 
    :declaring-class java.util.Date, 
    :parameter-types [long], 
    :exception-types [], 
    :flags #{:public}} 
    {:name getTimeImpl, 
    :return-type long, 
    :declaring-class java.util.Date, 
    :parameter-types [], 
    :exception-types [], 
    :flags #{:private :final}} 
    {:name setYear, 
    :return-type void, 
    :declaring-class java.util.Date, 
    :parameter-types [int], 
    :exception-types [], 
    :flags #{:public}} 
    {:name normalize, 
    :return-type sun.util.calendar.BaseCalendar$Date, 
    :declaring-class java.util.Date, 
    :parameter-types [sun.util.calendar.BaseCalendar$Date], 
    :exception-types [], 
    :flags #{:private :final}} 
    {:name getHours, 
    :return-type int, 
    :declaring-class java.util.Date, 
    :parameter-types [], 
    :exception-types [], 
    :flags #{:public}} 
    {:name getYear, 
    :return-type int, 
    :declaring-class java.util.Date, 
    :parameter-types [], 
    :exception-types [], 
    :flags #{:public}} 
    {:name java.util.Date, 
    :declaring-class java.util.Date, 
    :parameter-types [int int int int int int], 
    :exception-types [], 
    :flags #{:public}} 
    {:name java.util.Date, 
    :declaring-class java.util.Date, 
    :parameter-types [], 
    :exception-types [], 
    :flags #{:public}} 
    {:name UTC, 
    :return-type long, 
    :declaring-class java.util.Date, 
    :parameter-types [int int int int int int], 
    :exception-types [], 
    :flags #{:static :public}} 
    {:name getTime, 
    :return-type long, 
    :declaring-class java.util.Date, 
    :parameter-types [], 
    :exception-types [], 
    :flags #{:public}} 
    {:name getJulianCalendar, 
    :return-type sun.util.calendar.BaseCalendar, 
    :declaring-class java.util.Date, 
    :parameter-types [], 
    :exception-types [], 
    :flags #{:synchronized :private :static :final}} 
    {:name getCalendarSystem, 
    :return-type sun.util.calendar.BaseCalendar, 
    :declaring-class java.util.Date, 
    :parameter-types [sun.util.calendar.BaseCalendar$Date], 
    :exception-types [], 
    :flags #{:private :static :final}} 
    {:name setTime, 
    :return-type void, 
    :declaring-class java.util.Date, 
    :parameter-types [long], 
    :exception-types [], 
    :flags #{:public}} 
    {:name setMinutes, 
    :return-type void, 
    :declaring-class java.util.Date, 
    :parameter-types [int], 
    :exception-types [], 
    :flags #{:public}} 
    {:name cdate, 
    :type sun.util.calendar.BaseCalendar$Date, 
    :declaring-class java.util.Date, 
    :flags #{:transient :private}} 
    {:name getDay, 
    :return-type int, 
    :declaring-class java.util.Date, 
    :parameter-types [], 
    :exception-types [], 
    :flags #{:public}} 
    {:name toString, 
    :return-type java.lang.String, 
    :declaring-class java.util.Date, 
    :parameter-types [], 
    :exception-types [], 
    :flags #{:public}} 
    {:name java.util.Date, 
    :declaring-class java.util.Date, 
    :parameter-types [int int int int int], 
    :exception-types [], 
    :flags #{:public}} 
    {:name java.util.Date, 
    :declaring-class java.util.Date, 
    :parameter-types [int int int], 
    :exception-types [], 
    :flags #{:public}} 
    {:name toInstant, 
    :return-type java.time.Instant, 
    :declaring-class java.util.Date, 
    :parameter-types [], 
    :exception-types [], 
    :flags #{:public}} 
    {:name clone, 
    :return-type java.lang.Object, 
    :declaring-class java.util.Date, 
    :parameter-types [], 
    :exception-types [], 
    :flags #{:public}} 
    {:name from, 
    :return-type java.util.Date, 
    :declaring-class java.util.Date, 
    :parameter-types [java.time.Instant], 
    :exception-types [], 
    :flags #{:static :public}} 
    {:name compareTo, 
    :return-type int, 
    :declaring-class java.util.Date, 
    :parameter-types [java.util.Date], 
    :exception-types [], 
    :flags #{:public}} 
    {:name toLocaleString, 
    :return-type java.lang.String, 
    :declaring-class java.util.Date, 
    :parameter-types [], 
    :exception-types [], 
    :flags #{:public}} 
    {:name convertToAbbr, 
    :return-type java.lang.StringBuilder, 
    :declaring-class java.util.Date, 
    :parameter-types [java.lang.StringBuilder java.lang.String], 
    :exception-types [], 
    :flags #{:private :static :final}} 
    {:name getTimezoneOffset, 
    :return-type int, 
    :declaring-class java.util.Date, 
    :parameter-types [], 
    :exception-types [], 
    :flags #{:public}} 
    {:name toGMTString, 
    :return-type java.lang.String, 
    :declaring-class java.util.Date, 
    :parameter-types [], 
    :exception-types [], 
    :flags #{:public}} 
    {:name normalize, 
    :return-type sun.util.calendar.BaseCalendar$Date, 
    :declaring-class java.util.Date, 
    :parameter-types [], 
    :exception-types [], 
    :flags #{:private :final}} 
    {:name parse, 
    :return-type long, 
    :declaring-class java.util.Date, 
    :parameter-types [java.lang.String], 
    :exception-types [], 
    :flags #{:static :public}} 
    {:name jcal, 
    :type sun.util.calendar.BaseCalendar, 
    :declaring-class java.util.Date, 
    :flags #{:private :static}} 
    {:name gcal, 
    :type sun.util.calendar.BaseCalendar, 
    :declaring-class java.util.Date, 
    :flags #{:private :static :final}} 
    {:name before, 
    :return-type boolean, 
    :declaring-class java.util.Date, 
    :parameter-types [java.util.Date], 
    :exception-types [], 
    :flags #{:public}} 
    {:name compareTo, 
    :return-type int, 
    :declaring-class java.util.Date, 
    :parameter-types [java.lang.Object], 
    :exception-types [], 
    :flags #{:synthetic :bridge :public}} 
    {:name getDate, 
    :return-type int, 
    :declaring-class java.util.Date, 
    :parameter-types [], 
    :exception-types [], 
    :flags #{:public}} 
    {:name readObject, 
    :return-type void, 
    :declaring-class java.util.Date, 
    :parameter-types [java.io.ObjectInputStream], 
    :exception-types 
    [java.io.IOException java.lang.ClassNotFoundException], 
    :flags #{:private}} 
    {:name setHours, 
    :return-type void, 
    :declaring-class java.util.Date, 
    :parameter-types [int], 
    :exception-types [], 
    :flags #{:public}} 
    {:name getCalendarSystem, 
    :return-type sun.util.calendar.BaseCalendar, 
    :declaring-class java.util.Date, 
    :parameter-types [long], 
    :exception-types [], 
    :flags #{:private :static :final}} 
    {:name equals, 
    :return-type boolean, 
    :declaring-class java.util.Date, 
    :parameter-types [java.lang.Object], 
    :exception-types [], 
    :flags #{:public}} 
    {:name java.util.Date, 
    :declaring-class java.util.Date, 
    :parameter-types [java.lang.String], 
    :exception-types [], 
    :flags #{:public}}}} 
nil 
user> 

有時,它更容易使用bean看到存在的各個領域。

user> (clojure.pprint/pprint (bean (java.util.Date.))) 
{:seconds 9, 
:date 30, 
:class java.util.Date, 
:minutes 13, 
:hours 8, 
:year 114, 
:timezoneOffset 420, 
:month 7, 
:day 6, 
:time 1409411589031} 
nil 

使用reflect/reflect列出所有方法的名字(如你在你的例子做):

user> (->> (reflect/reflect (java.util.Date.)) :members (filter :return-type) (map :name)) 
(getSeconds getCalendarDate after hashCode setMonth getMonth getCalendarSystem writeObject getMillisOf getMinutes setDate setSeconds getTimeImpl setYear normalize getHours getYear UTC getTime getJulianCalendar getCalendarSystem setTime setMinutes getDay toString toInstant clone from compareTo toLocaleString convertToAbbr getTimezoneOffset toGMTString normalize parse before compareTo getDate readObject setHours getCalendarSystem equals) 
+0

謝謝你,非常好,但仍然冗長和缺少過濾部分(當然不難實現功能)。我會探索它。 – 2014-08-30 15:22:34

+1

過濾可以使用與其他任何本地clojure數據完成的相同方式完成。例如,你可以通過'( - >>(reflect/reflect(java.util.Date。)):members(filter:return-type))'來獲得只有方法,你可以進一步過濾去除返回或取出的方法某些類型或參數計數... – noisesmith 2014-08-30 15:42:36

3

看一看iroh

> (.? String #"^conta") ;; grep all fields/methods that start with conta 
(#[contains :: (java.lang.String, java.lang.CharSequence) -> boolean]) 
> (.? String #"^con" :name) ;; return just the name of the method/field 
("concat" "contains" "contentEquals") 
> (.? "string instance" #"^con" :name) ;; works with instances also 
("concat" "contains" "contentEquals") 
> (.? "a string instance" :static :name :public :method) ; all public static methods 
("copyValueOf" "format" "join" "valueOf") 
> (.? "a string instance" #"^t" :instance :name :public :method) ;; all public instance methods that start with t 
("toCharArray" "toLowerCase" "toString" "toUpperCase" "trim") 
+0

哇,這就是我一直在尋找的! – 2014-08-30 15:55:35

+0

那麼你可以接受嗎? :) – DanLebrero 2014-09-04 00:57:00

+0

我在這個和另一個之間撕裂,我想等待看看有多少票都收到。 – 2014-09-04 14:39:28