If I want to access a property called transform
I could do it this way:
(. obj transform)
But what if I have a variable and want to access a property with the same name as the value of the variable:
(let [prop 'transform] (. obj prop))
This obviously doesn’t work, but how do I make it work? I tried doing things like:
(eval `(. ~'obj ~prop))
But eval
won’t help me since prop
is lexically bound.
Is there just a function version of .
lying around?
Maybe something like this?
(defmacro call-by-string [obj prop]
`(. ~obj ~(symbol prop)))
so you can do:
(call-by-string "foo" "length") ;;=> 3
Sadly this won’t work, since if you put a variable rather than a value in the second parameter, it will break:
(let [prop "length"] (call-by-string "foo" prop))
;;=> ... Cannot find instance field/property/member name prop
And this is how it looks if you macroexpand:
(let [prop "length"]
(macroexpand '(call-by-string "foo" prop)))
;;=> (. "foo" prop)
This also works, but it uses reflection:
(clojure.lang.Reflector/invokeInstanceMethod "foo" "length" (into-array [])) ;;=> 3
2 Likes
Thanks bork, reflection is perfectly fine in this case. It was something like this I was looking for. I’ll try it out soon.
EDIT: Worked perfectly, thanks.
system
Closed
6
This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.