Reputation: 31192
I have a clojure map
+ 69 (def names {:production "prayag"
+ 70 :staging "upd"})
I need to get a value from a key variable environment
that would be dynamic.
Something like below throws Exception,
+ 72 (defn get-name [environment]
+ 73 (let [
+ 74 name (:(environment) names)]
+ 75 println name
+ 76 ))
Stacktrace
Caused by: java.lang.RuntimeException: Invalid token: :
at clojure.lang.Util.runtimeException(Util.java:219)
at clojure.lang.LispReader.interpretToken(LispReader.java:326)
at clojure.lang.LispReader.read(LispReader.java:211)
at clojure.lang.LispReader.readDelimitedList(LispReader.java:1157)
at clojure.lang.LispReader$ListReader.invoke(LispReader.java:982)
at clojure.lang.LispReader.readDelimitedList(LispReader.java:1148)
at clojure.lang.LispReader$VectorReader.invoke(LispReader.java:1083)
at clojure.lang.LispReader.readDelimitedList(LispReader.java:1148)
at clojure.lang.LispReader$ListReader.invoke(LispReader.java:982)
at clojure.lang.LispReader.readDelimitedList(LispReader.java:1148)
at clojure.lang.LispReader$ListReader.invoke(LispReader.java:982)
at clojure.lang.LispReader.read(LispReader.java:185)
at clojure.lang.Compiler.load(Compiler.java:7060)
... 55 more
While following code,
+ 72 (defn get-name [env]
+ 73 (let [
+ 74 name (keyword(":" env) names)]
+ 75 println name
+ 76 ))
gives
Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn
at nepleaks_engine.util.utility$fn__3885.invoke(utility.clj:74)
at clojure.lang.AFn.applyToHelper(AFn.java:159)
at clojure.lang.AFn.applyTo(AFn.java:151)
at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3458)
... 58 more
And
+ 72 (defn get-name [env]
+ 73 (let [
+ 74 name (.get names env)]
+ 75 println name
+ 76 ))
gives
java.lang.NullPointerException
at nepleaks_engine.util.utility$util.invoke(utility.clj:81)
at nepleaks_engine.core$_main.invoke(core.clj:14)
at clojure.lang.Var.invoke(Var.java:411)
at user$eval5$fn__7.invoke(form-init336568295343421746.clj:1)
at user$eval5.invoke(form-init336568295343421746.clj:1)
at clojure.lang.Compiler.eval(Compiler.java:6619)
at clojure.lang.Compiler.eval(Compiler.java:6609)
at clojure.lang.Compiler.load(Compiler.java:7064)
at clojure.lang.Compiler.loadFile(Compiler.java:7020)
at clojure.main$load_script.invoke(main.clj:294)
at clojure.main$init_opt.invoke(main.clj:299)
at clojure.main$initialize.invoke(main.clj:327)
at clojure.main$null_opt.invoke(main.clj:362)
at clojure.main$main.doInvoke(main.clj:440)
at clojure.lang.RestFn.invoke(RestFn.java:421)
at clojure.lang.Var.invoke(Var.java:419)
at clojure.lang.AFn.applyToHelper(AFn.java:163)
at clojure.lang.Var.applyTo(Var.java:532)
at clojure.main.main(main.java:37)
Upvotes: 4
Views: 2636
Reputation: 20194
(:(environment) names)
is not a valid form. Unless environment
is a function of no arguments, you will get an error from wrapping it in parens. usage of :
to create keywords is done at read time, before (environment)
is evaluated, so you do not see the previous error, and the reader attempts to resolve :
on its own, which is not a valid input to the reader.
(keyword(":" env) names)
attempts to call the string ":" as if it were a function. It is not one. Also the spacing leads me to beleive that you expect keyword(arg)
to work as it would in an Algol family language. It will not. The proper usage is (keyword arg)
.
here is what works, with a few equivalent syntaxes avaliable for convenience (they all do the same thing):
user> (def names {:production "prayag" :staging "upd"})
#'user/names
user> (def environment "staging")
#'user/environment
user> (names (keyword environment))
"upd"
user> ((keyword environment) names)
"upd"
user> (get names (keyword environment))
"upd"
Upvotes: 12