Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

taking java method names as function arg in clojure

All,

I want to create a function that takes a symbol representing a java method and applies it to some object:

(user=> (defn f [m] (. "foo" (m)))

When I execute this, I get a result much different from what I expect

user=> (f 'getClass)
java.lang.IllegalArgumentException: No matching method found: m for class java.lang.String (NO_SOURCE_FILE:0)

2 questions:

1> why is the symbol m being called as the second arg of the '.' function instead of the value bound to m?

2> how would I actually do what I want to do?

like image 223
Nick Orton Avatar asked Dec 10 '22 18:12

Nick Orton


1 Answers

It's not working because . is a special form and has special evaluation rules. Normal function calls evaluate their arguments, but . doesn't evaluate the method-name parameter.

To make it work, either use eval or change your function into a macro.

user=> (defmacro foo [o m] `(. ~o ~m))
#'user/foo
user=> (foo 123 toString)
"123"
user=> (defn bar [o m] (eval `(. ~o ~m)))
#'user/bar
user=> (bar 123 'toString)
"123"

Use of eval generally isn't recommended.

like image 161
Brian Carper Avatar answered Dec 22 '22 09:12

Brian Carper