web-dev-qa-db-fra.com

Comment puis-je obtenir les méthodes d'une classe Java de Clojure?

Comment puis-je obtenir les méthodes d'une classe Java de Clojure?

61
Yazz.com

[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")
59
semperos

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}}
...
24
Stuart Sierra

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)
21
zcaudate

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"))
15
dbyrne

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

6
k1m190r

Essayez ma nouvelle bibliothèque:

http://github.com/zcaudate/iroh

(.? String  #"^c" :name)
;;=> ["charAt" "checkBounds" "codePointAt" "codePointBefore"
;;    "codePointCount" "compareTo" "compareToIgnoreCase".   
;;    "concat" "contains" "contentEquals" "copyValueOf"]
4
zcaudate