Shadowing global names
A nice article on Clojure that gives one wrong tip: to use #'var-name
to access a shadowed global.
Don’t do that! You’d better use namespace-where-defined-or-alias/var-name
.
There are several reasons not to use #'var-name
:
- it doesn’t work if the value of your var is not invokable,
- it evaluates to something different: it returns the var an not its value. It happens that vars proxy function calls to their values but a var can be rebound:
(def a (map str (range 10))) (def b (map #'str (range 10))) (take 5 a) <i>("0" "1" "2" "3" "4")</i> (take 5 b) <i>("0" "1" "2" "3" "4")</i> (binding [str identity] (doall a)) <i>("0" "1" "2" "3" "4" "5" "6" "7" "8" "9")</i> (binding [str identity] (doall b)) <i>("0" "1" "2" "3" "4" <strong>5 6 7 8 9</strong>)</i>
NB: @#'var-name
is better than #'var-name
but, really, just use the namespaced symbol.
Thanks Christophe!
I’ll correct it on the blog.
Eric