Comment puis-je obtenir les méthodes d'une classe Java de Clojure?
Réponses
Trop de publicités?[EDIT 2]
Par M Smith commentaire ci-dessous, il accomplit la même, mais fournit le tri par nom de la méthode et retourne uniquement les méthodes:
(print-table
(sort-by :name
(filter :exception-types (:members (r/reflect "foo")))))
[/EDIT 2]
[MODIFIER]
Ma réponse originale à cette question se réfère à Clojure 1.2, mais les choses ont changé avec Clojure 1.3. Cela fonctionne sans aucun recours sur Clojure contrib de bibliothèques d'aujourd'hui:
(require '[clojure.reflect :as r])
(use '[clojure.pprint :only [print-table]])
(print-table (:members (r/reflect "foo")))
De ce fait, plus découplé approche, avec l' reflect
fonction de fournir toutes sortes d'informations sur l'argument passé (dans ce cas, un String
"foo"
) et l' print-table
fonction prenant un médicament générique de tableaux de données de la structure et de la jolie impression en tant que tel.
C'est à l'origine de ce fil de discussion sur le Groupe Google.
[/EDIT]
J'utiliserais show
fonction dans l' clojure.contrib.repl-utils
d'espace de noms, ce qui permet d'imprimer toutes les statiques et les membres de l'instance d'un objet (ou d'une catégorie d'un objet). J'ai besoin d'elle de la sorte:
(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 vous pouvez tout simplement passer à une classe d' show
, tandis que le second montre que vous pouvez passer une instance de la classe.
Bien sûr, cela fonctionne pour beaucoup de Clojure éléments qui sont des classes Java dessous. Voici un exemple de voir toutes les méthodes disponibles pour une instance de java.lang.Chaîne de caractères:
(ru/show "foo")
Essayez clojure.reflect , disponible dans les dernières versions 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)