フィールドとメソッド探しにちょっと便利な関数を作ってみた
SLIMEで開発している際に、Javaのクラスが持つフィールドやメソッド名を調べたい事がある。
例えば、文字列を大文字に変換するメソッドを忘れてしまって、uppercaseだったかな?toUpperだったかな?なんて時に、ちょっと便利な関数。
使い方
(inspect 調べたいオブジェクトまたはクラス マッチ文字列)
すべてのフィールド・メソッドを表示したい場合は
(inspect 調べたいオブジェクトまたはクラス)
とする。
使用例
user> (use 'tools) ; tools名前空間をuseする nil user> (inspect String "upper") ; Stringクラスをupperで調べる String toUpperCase(Locale) String toUpperCase() nil user> (inspect Integer) ; Integerクラスの全てのフィールド・メソッドを調べる Integer MIN_VALUE Integer MAX_VALUE Integer TYPE Integer SIZE int hashCode() int reverseBytes(int) boolean equals(Object) ...略... user> (inspect 1.0 "infi") ; オブジェクトを指定しても良い Double NEGATIVE_INFINITY Double POSITIVE_INFINITY boolean isInfinite(double) boolean isInfinite() nil user>
コード
(ns tools (:use [clojure.contrib.str-utils :only (str-join)])) (defn to-class [obj] (if (class? obj) obj (class obj))) (defn- filter-name [coll s] (filter #(not= (.. % getName toUpperCase (indexOf s)) -1) (sort-by #(. % getName) coll))) (defn- match-field [cls s] (let [fields (. cls getFields)] (if s (filter-name fields s) fields))) (defn- match-method [cls s] (let [methods (. cls getMethods)] (if s (filter-name methods s) methods))) (defn inspect ([obj] (inspect obj nil)) ([obj s] (let [cls (to-class obj) mstr (if s (. s toUpperCase))] (doseq [field (match-field cls mstr)] (let [field-name (. field getName) class-name (.. field getDeclaringClass getSimpleName)] (println (str class-name " " field-name)))) (doseq [method (match-method cls mstr)] (let [method-name (. method getName) return-class-name (.. method getReturnType getSimpleName) param-class-names (for [param-class (. method getParameterTypes)] (. param-class getSimpleName))] (println (str return-class-name " " method-name "(" (str-join ", " param-class-names) ")")))))))