0

I'm setting up config map using environ for fetching up env variables. Since environ normalizes upper case to lowercase and "_" characters to "-", I ended up with repetitions of keywords

(def config {:consumer-key (env :consumer-key)
             :keystore-password (env :consumer-key)
             :ssl-keystore-password (env :ssl-keystore-password)
             :ssl-certificate-name (env :ssl-certificate-name)
             :callback-url (env :callback-url)
             :mp-private-key (env :mp-private-key)
             :merchant-checkout-id (env :merchant-checkout-id)
             :is-sandbox (env :is-sandbox)})

is there a way to prevent this repetition? maybe a function which receives a keyword and returns some kind of key value pair for the map?

Shlomi
  • 4,708
  • 1
  • 23
  • 32
prog keys
  • 687
  • 1
  • 5
  • 14
  • 3
    Could you use [`select-keys`](http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/select-keys) to create the `config` map? – glts Dec 28 '16 at 20:47

2 Answers2

3

As mentioned in the comments, since env is a map you can just use select-keys with a list of keys to copy:

(def config
  (select-keys env [:consumer-key :is-sandbox
                    :keystore-password :ssl-keystore-password :ssl-certificate-name
                    :callback-url :mp-private-key :merchant-checkout-id]))

Alan Thompson's approach is reasonable if you have an arbitrary function rather than specifically a map.

amalloy
  • 89,153
  • 8
  • 140
  • 205
  • Since he is using the `environ` library then `env` is indeed a function: https://github.com/weavejester/environ#usage – Alan Thompson Dec 28 '16 at 23:37
  • If i remember correctly, it ic a map really. "Lets pull the database connection details from the key :database-url on the environ.core/env map." (From docs).. so @amalloy's answer should be correct – leetwinski Dec 29 '16 at 06:09
  • It's definitely a map: https://github.com/weavejester/environ/blob/master/environ/src/environ/core.clj#L39 – amalloy Dec 29 '16 at 07:04
0

Here is one way to do it by defining a helper function:

(def env {:consumer-key   1
          :ssl-key        2
          :mp-private-key 3})

(def key-list (keys env))

(defn extract-from
  [src-fn keys]
  (into (sorted-map)
    (for [key keys]
      {key (src-fn key)} )))

(println "result:" (extract-from env key-list))

=> result: {:consumer-key 1, :mp-private-key 3, :ssl-key 2}

Note that for testing purposes I used a trick and substituted a map env for the function env from the environ library. This works since a map can act like a function when looking up its keys. It will still work for an actual function like environ.core/env.

Alan Thompson
  • 29,276
  • 6
  • 41
  • 48