Javaオブジェクトに対して指定のメソッド名に対する値を取ってリストで返すClojureのマクロを作った

いやbeanを使えばいいという話もあるのですが、ちょっと必要に迫られて作りました。

(defmacro obj-values
  "Takes a Java object and method names, returns a list of method values."
  ([obj] '[])
  ([obj methodname] `[(. ~obj ~methodname)])
  ([obj methodname & methodnames] `(concat (obj-values ~obj ~methodname) (obj-values ~obj ~@methodnames)))

結果はこんな感じ。beanでは取得できない値も取得できます。

user=> (obj-values (java.io.File. ".") lastModified canRead canWrite)
(1275298723575 true true)

何故こんなマクロを作ったか。
あるクラスにgetHoge()というメソッドがあったとして、うっかりそのサブクラスにisHoge()なるメソッドを作ってしまったところ、サブクラスに対してbeanするとisHoge()の結果しか取れなくなったためです orz


本当はmethodnameに相当するkeywordを作ってマップで返したかったのですが、symbolからkeywordを作る手段が思いつかず、断念しました。
とは言えとりあえず上記のマクロがあれば今回は事足りるので、よしとします。

※リフレクションを使えば可能ですが、速度面を考慮してやめました。