Как я могу получить методы класса Java из Clojure?


Как я могу получить методы класса Java из Clojure?

6 59

6 ответов:

[EDIT 2]

в комментарии M Smith ниже, это выполняет то же самое, но обеспечивает сортировку по имени метода и возвращает только методы:

(print-table
  (sort-by :name 
    (filter :exception-types (:members (r/reflect "foo")))))

[/EDIT 2]

[EDIT]

мой первоначальный ответ относится к Clojure 1.2, но все изменилось с Clojure 1.3. Это работает без какой-либо зависимости от библиотек contrib Clojure в настоящее время:

(require '[clojure.reflect :as r])
(use '[clojure.pprint :only [print-table]])

(print-table (:members (r/reflect "foo")))

это обеспечивает значительно более развязанный подход, с reflect функция, предоставляющая все виды информации о переданном аргументе (в данном случае a String"foo") и print-table функция, принимающая любую общую табличную структуру данных и довольно печатающую ее как таковую.

Это изначально от эта тема в группе Google.

[/EDIT]

я бы использовать

попробовать clojure.задумайтесь, доступно в последних версиях Clojure 1.3.0-alpha*. Он возвращает структуры данных Clojure, что вы можете искать/фильтровать по мере необходимости.

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}}
...

вы можете использовать этот метод, который использует clojure.задумайтесь и расширьте предыдущие ответы:

(use 'clojure.reflect)

(defn all-methods [x]
    (->> x reflect 
           :members 
           (filter :return-type)  
           (map :name) 
           sort 
           (map #(str "." %) )
           distinct
           println))

использование:

 (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)

этот код будет печатать все открытые методы, как объявленные, так и унаследованные.

(doseq [m (.getMethods (type "Hello"))]
  (println "Method Name: " (.getName m))
  (println "Return Type: " (.getReturnType m) "\n"))

это вернет Java массив объявленных методов:

(:declaredMethods (bean String))

(seq (:declaredMethods (bean String)))

преимущество Боб находится в clojure.ядро

попробуйте мою новую библиотеку:

http://github.com/zcaudate/iroh

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