reflect

added
1.3

ns
clojure.reflect

type
function

(reflect obj & options)

Alpha - subject to change.
Reflect on the type of obj (or obj itself if obj is a class).
Return value and options are the same as for type-reflect. 

                (use 'clojure.reflect 'clojure.pprint)
;;=> nil
(def r (reflect *in*))
;;=> #'user/r
(count (:members r))
;;=> 9
(pprint (map class (:members r)))
;;  (clojure.reflect.Constructor
;;   clojure.reflect.Method
;;   clojure.reflect.Field
;;   clojure.reflect.Field
;;   clojure.reflect.Method
;;   clojure.reflect.Method
;;   clojure.reflect.Method
;;   clojure.reflect.Method
;;   clojure.reflect.Field)
;;=> nil
(pprint r)
;;   {:bases #{java.io.PushbackReader},
;;    :flags #{:public},
;;    :members
;;     #{{:name clojure.lang.LineNumberingPushbackReader,
;;        :declaring-class clojure.lang.LineNumberingPushbackReader,
;;        :parameter-types [java.io.Reader],
;;        :exception-types [],
;;        :flags #{:public}}
;;       {:name read,
;;        :return-type int,
;;        :declaring-class clojure.lang.LineNumberingPushbackReader,
;;        :parameter-types [],
;;        :exception-types [java.io.IOException],
;;        :flags #{:public}}
;;       {:name _atLineStart,
;;        :type boolean,
;;        :declaring-class clojure.lang.LineNumberingPushbackReader,
;;        :flags #{:private}}
;;       {:name newline,
;;        :type int,
;;        :declaring-class clojure.lang.LineNumberingPushbackReader,
;;        :flags #{:private :static :final}}
;;       {:name unread,
;;        :return-type void,
;;        :declaring-class clojure.lang.LineNumberingPushbackReader,
;;        :parameter-types [int],
;;        :exception-types [java.io.IOException],
;;        :flags #{:public}}
;;       {:name readLine,
;;        :return-type java.lang.String,
;;        :declaring-class clojure.lang.LineNumberingPushbackReader,
;;        :parameter-types [],
;;        :exception-types [java.io.IOException],
;;        :flags #{:public}}
;;       {:name atLineStart,
;;        :return-type boolean,
;;        :declaring-class clojure.lang.LineNumberingPushbackReader,
;;        :parameter-types [],
;;        :exception-types [],
;;        :flags #{:public}}
;;       {:name getLineNumber,
;;        :return-type int,
;;        :declaring-class clojure.lang.LineNumberingPushbackReader,
;;        :parameter-types [],
;;        :exception-types [],
;;        :flags #{:public}}
;;       {:name _prev,
;;        :type boolean,
;;        :declaring-class clojure.lang.LineNumberingPushbackReader,
;;        :flags #{:private}}}}
;;=> nil

            
                (require '[clojure.reflect :as cr])
(require '[clojure.pprint :as pp])

;; Here we have a simple function that prints the
;; important bits of the class definition in a table.
(->> String 
     cr/reflect 
     :members 
     pp/print-table))
;;=> [produces a large table the next example filters it down.

;; In order to reduce the rows to just :public methods a filter can be used.
(->> String 
     cr/reflect 
     :members 
     (filter #(contains? (:flags %) :public)) 
     pp/print-table)
;;=> |                  :name |     :return-type | :declaring-class | <etc.> 
;;   |------------------------+------------------+------------------+------->
;;   |             replaceAll | java.lang.String | java.lang.String | 
;;   | CASE_INSENSITIVE_ORDER |                  | java.lang.String | 
;;   |         codePointCount |              int | java.lang.String |
;;   |               getChars |             void | java.lang.String | 
;; etc.

;; Print methods that contain "to", as a way of code completion.
;; Combine with above example ``#(contains? (:flags %) :public)`` to get 
;; matching callable methods (public & with "to")
(->> String 
     cr/reflect 
     :members 
     (filter #(.contains (str (:name %)) "to"))
     pp/print-table)

;; => |       :name |     :return-type | :declaring-class | <etc.>  
;;    |-------------+------------------+------------------+---
;;    |    toString | java.lang.String | java.lang.String |   
;;    | toLowerCase | java.lang.String | java.lang.String |   
;;    | toUpperCase | java.lang.String | java.lang.String |   
;;    | toUpperCase | java.lang.String | java.lang.String | 
;;    | toCharArray |           char<> | java.lang.String | 
;;    | toLowerCase | java.lang.String | java.lang.String |
            
                (require '[clojure.reflect :as cr])
(import  '(clojure.reflect.JavaReflector))

;; Let us see what is available in the JavaReflector
(->> clojure.reflect.JavaReflector 
     cr/reflect
     :members
     (sort-by :name)
     (pp/print-table [:name :flags :parameter-types])
;; |                         :name |                    :flags |   :parameter-types |
;; |-------------------------------+---------------------------+--------------------|
;; |             __cached_class__0 |       #{:private :static} |                    |
;; |                   classloader |         #{:public :final} |                    |
;; | clojure.reflect.JavaReflector |                #{:public} | [java.lang.Object] |
;; |                      const__0 | #{:public :static :final} |                    |
;; |                      const__1 | #{:public :static :final} |                    |
;; |                     const__10 | #{:public :static :final} |                    |
;; |                      const__5 | #{:public :static :final} |                    |
;; |                      const__7 | #{:public :static :final} |                    |
;; |                      const__9 | #{:public :static :final} |                    |
;; |                    do_reflect |                #{:public} | [java.lang.Object] |
;; |                      getBasis |        #{:public :static} |                 [] |
;;=> nil