Skip to content

Instantly share code, notes, and snippets.

@Sh4pe
Last active April 11, 2018 05:39
Show Gist options
  • Select an option

  • Save Sh4pe/eea52891dbeca5d0614d to your computer and use it in GitHub Desktop.

Select an option

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
Copy Markdown

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
Copy Markdown

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

@puredanger
Copy link
Copy Markdown

nope, typo :) (but either works)

@Sh4pe
Copy link
Copy Markdown
Author

Sh4pe commented Dec 8, 2017

Thank you for your hints, gentlemen! :)

@jwhitlark
Copy link
Copy Markdown

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