Skip to content

Instantly share code, notes, and snippets.

@Sh4pe
Last active April 11, 2018 05:39
Show Gist options
  • Save Sh4pe/eea52891dbeca5d0614d to your computer and use it in GitHub Desktop.
Save Sh4pe/eea52891dbeca5d0614d to your computer and use it in GitHub Desktop.
Pretty-print methods of a Java class in Clojure. Useful inside the REPL.

The function print-methods is intended to be used inside a REPL. Just copy and paste it to your REPL and enjoy:

main=> ; paste print-methods
main=> (print-methods 1)
class java.lang.Long
-----------
bitCount(long) -> int
byteValue() -> byte
compare(long, long) -> int
;...
(defn print-methods
"For a class 'x', print the methods (ordered by their name) in
the following fashion:
<methodName>(<parameters if any>) -> <return value>"
[x]
(let [meth-seq (-> x class .getMethods seq)
ordered-seq (sort-by #(.getName %) meth-seq)
params (fn [m]
(let [ptypes (.getParameterTypes m)]
(if (= 0 (count ptypes))
""
(clojure.string/join ", "
(for [x ptypes]
(.getName x))))))]
(printf "class %s\n-----------\n" (-> x class .getName))
(doseq [m ordered-seq]
(printf "%s(%s) -> %s\n" (.getName m) (params m) (.getReturnType m)))))
@puredanger
Copy link

puredanger commented Dec 8, 2017

Nice! The built-in clojure.reflect does all the Java reflection to Clojure data conversion by for you by the way, so you could just rewrite this in terms of Clojure data processing too (see clojure.reflect/type-reflect for details on the format):

(use 'clojure.reflect)
(defn print-methods [c]
  (->> (reflect c) 
       :members 
       (filter :return-type)
       (sort-by :name)
       (map (fn [{:keys [name parameter-types return-type]}]
              (format "%s(%s) -> %s" name (clojure.string/join ", " parameter-types) return-type)))
       (run! println)))
(print-methods Long)

bitCount(long) -> int
byteValue() -> byte
compare(long, long) -> int
...

@jimmyhmiller
Copy link

@puredanger Any reason for making :return-type a keyword instead of a symbol in the :keys clause?

@puredanger
Copy link

nope, typo :) (but either works)

@Sh4pe
Copy link
Author

Sh4pe commented Dec 8, 2017

Thank you for your hints, gentlemen! :)

@jwhitlark
Copy link

clojure.print/print-table works too.

(use 'clojure.pprint)
(defn print-methods-2 [c]
  (->> (reflect c) 
       :members 
       (filter :return-type)
       (sort-by :name)
       (map #(select-keys % [:name :parameter-types :return-type])) 
       (print-table)))
|                 :name |                  :parameter-types |         :return-type |
|-----------------------+-----------------------------------+----------------------|
|              bitCount |                            [long] |                  int |
|             byteValue |                                [] |                 byte |
|               compare |                       [long long] |                  int |
|             compareTo |                [java.lang.Object] |                  int |
|             compareTo |                  [java.lang.Long] |                  int |
|       compareUnsigned |                       [long long] |                  int |
|                decode |                [java.lang.String] |       java.lang.Long |

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment