Comment puis-je obtenir les méthodes d'une classe Java de Clojure?
[EDIT 2]
Selon le commentaire de M Smith ci-dessous, cela accomplit la même chose mais fournit un tri par nom de méthode et ne renvoie que les méthodes:
(print-table
(sort-by :name
(filter :exception-types (:members (r/reflect "foo")))))
[/ EDIT 2]
[MODIFIER]
Ma réponse originale fait référence à Clojure 1.2, mais les choses ont changé avec Clojure 1.3. Cela fonctionne sans aucune dépendance sur les bibliothèques de contributions de Clojure maintenant:
(require '[clojure.reflect :as r])
(use '[clojure.pprint :only [print-table]])
(print-table (:members (r/reflect "foo")))
Cela fournit une approche beaucoup plus découplée, avec la fonction reflect
fournissant toutes sortes d'informations sur l'argument passé (dans ce cas, un String
"foo"
) et le print-table
fonction prenant n'importe quelle structure de données tabulaire générique et l'imprimant comme telle.
Il s'agit à l'origine de ce fil sur le groupe Google .
[/ MODIFIER]
J'utiliserais la fonction show
dans le clojure.contrib.repl-utils
namespace, qui affichera tous les membres statiques et d'instance d'un objet (ou d'une classe d'un objet). J'en ai besoin comme ça:
(require '[clojure.contrib.repl-utils :as ru])
Voici un exemple d'utilisation de Joda Time:
(import 'org.joda.time.DateTime)
(ru/show DateTime)
(ru/show (DateTime.))
Le premier exemple montre comment passer simplement une classe à show
, tandis que le second montre que vous pouvez également passer une instance de la classe.
Cela fonctionne bien sûr pour de nombreux éléments Clojure qui sont Java classes en dessous. Voici un exemple de voir toutes les méthodes disponibles pour une instance de Java.lang.String:
(ru/show "foo")
Essayez clojure.reflect , disponible dans les versions récentes de Clojure 1.3.0-alpha *. Il renvoie des structures de données Clojure que vous pouvez rechercher/filtrer selon vos besoins.
Clojure 1.3.0-alpha6
user=> (use 'clojure.reflect 'clojure.pprint)
nil
user=> (pprint (reflect "hello"))
{:bases
#{Java.io.Serializable Java.lang.Comparable Java.lang.Object
Java.lang.CharSequence},
:flags #{:public :final},
:members
#{{:name valueOf,
:return-type Java.lang.String,
:declaring-class Java.lang.String,
:parameter-types [boolean],
:exception-types [],
:flags #{:static :public}}
...
Vous pouvez utiliser cette méthode qui utilise clojure.reflect et étend les réponses précédentes:
(use 'clojure.reflect)
(defn all-methods [x]
(->> x reflect
:members
(filter :return-type)
(map :name)
sort
(map #(str "." %) )
distinct
println))
Usage:
(all-methods "")
; => (.charAt .checkBounds .codePointAt .codePointBefore .codePointCount .compareTo .compareToIgnoreCase .concat .contains .contentEquals .copyValueOf .endsWith .equals .equalsIgnoreCase .format .getBytes .getChars .hashCode .indexOf .intern .isEmpty .lastIndexOf .length .matches .offsetByCodePoints .regionMatches .replace .replaceAll .replaceFirst .split .startsWith .subSequence .substring .toCharArray .toLowerCase .toString .toUpperCase .trim .valueOf)
(all-methods 1)
; => (.bitCount .byteValue .compareTo .decode .doubleValue .equals .floatValue .getChars .getLong .hashCode .highestOneBit .intValue .longValue .lowestOneBit .numberOfLeadingZeros .numberOfTrailingZeros .parseLong .reverse .reverseBytes .rotateLeft .rotateRight .shortValue .signum .stringSize .toBinaryString .toHexString .toOctalString .toString .toUnsignedString .valueOf)
(all-methods Java.util.StringTokenizer)
; => (.countTokens .hasMoreElements .hasMoreTokens .isDelimiter .nextElement .nextToken .scanToken .setMaxDelimCodePoint .skipDelimiters)
Ce code imprimera toutes les méthodes publiques, déclarées et héritées.
(doseq [m (.getMethods (type "Hello"))]
(println "Method Name: " (.getName m))
(println "Return Type: " (.getReturnType m) "\n"))
cela renverra Java tableau de méthodes déclarées:
(:declaredMethods (bean String))
(seq (:declaredMethods (bean String)))
l'avantage est le haricot est dans clojure.core
Essayez ma nouvelle bibliothèque:
http://github.com/zcaudate/iroh
(.? String #"^c" :name)
;;=> ["charAt" "checkBounds" "codePointAt" "codePointBefore"
;; "codePointCount" "compareTo" "compareToIgnoreCase".
;; "concat" "contains" "contentEquals" "copyValueOf"]