This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
What is the most efficient way to solve the following? I have a vector of strings. I want to convert it to a vector of maps, with an incremented number on each. Example input ["red" "orange" "yellow"] Example output: [{:color "red" :number 1} {:color "orange" :number 2} {:color "yellow" :number 3} ]
(let [colors ["red" "orange" "yellow"]] (map (fn [color index] {:color color :number index}) colors (range)))
ah! I didn't realise map took multiple sets of arguments like that. thanks!
also didn't realise I can call range with no arguments. elegant!
yeah map can take multiple collections and is quite handy sometimes. here we use the property that it stops when any of the collections runs out of elements
yeah. (range)
gives back an infinite sequence but map
"terminates" when one of the collections (here, colors) runs out of elements
there's also map-indexed but i always forget which arg is the index so i just make my own.
(let [colors ["red" "orange" "yellow"]]
(map-indexed (fn [index color] {:color color :number index}) colors))
({:color "red", :number 0}
{:color "orange", :number 1}
{:color "yellow", :number 2})
huh, neat
(defn color-map [col]
(map-indexed #(into {} {:color %2 :number (inc %1)}) col))
Hello! What is the best way to use a different value for a binding when developing something?
So far I do have a dev
folder with user.clj
and I add it to paths with an alias when launching my development repl. I have a def
inside another namespace that i want to be different in dev (when developing/running the dev repl) and in prod (when running the app through uberjar)
https://clojuredocs.org/clojure.core/with-redefs will replace what you want for code you want
but for real you want to use https://github.com/weavejester/integrant and use configuration to startup parts of your system
for example this config warm up parts of the system and configure them
(def config
{:env/variables {:version (app-version)
:k_revision (System/getenv "K_REVISION")}
:db/postgresql {:uri (System/getenv "postgresql")}
:data-providers/binance {:auth {:api-key (System/getenv "binance_api_key")
:secret-key (System/getenv "binance_secret_key")}}
:logs/google-json-payload {:level (keyword (System/getenv "log_level"))
:is-loggable? (fn [{:keys [^String logger-name ^Level level]}]
(let [level-int (.intValue level)]
(not
(some (fn [{:keys [logger level]}]
(and (.startsWith logger-name logger)
(< level-int (google-json-payload/JUL-levels->int level))))
[{:logger "org.postgresql" :level :config}
{:logger "jdk.event.security" :level :config}
{:logger "okhttp3.internal" :level :config}
{:logger "sun.net.www.protocol.http.HttpURLConnection" :level :config}]))))
:pretty? (nil? (System/getenv "K_REVISION"))}
})
it is not in this example, but you can code :db/postgresql
as first one to run and service X to run after postgresql, because it depends on it
you want to end with such kind of setup, so let’s say with-redefs
is easy and fast to go now, but on the end it is worth to use configurations instead of with-redefs
Ah seems like a good fit! My first thought was that my whole project should have an 'entrypoint' (alternative from -main) that should take a config
and pass it down to the specific modules while it initializes them, and in that way I would have a (start prod-conf)
in -main
and a (start dev-conf)
in dev/user.clj
That did not seem very flexible though as I would need to pass wire/plumb every conf down to each specific module, I was searching more for a way to define maybe a def debug?
global definition somewhat like the goog.DEBUG
define available in shadow-cljs / re-frame projects
With integrant
can I specify / override part of the configuration in dev/user.clj
for development purposes?
:logs/google-json-payload {:level (keyword (System/getenv "log_level"))
:is-loggable? (fn [{:keys [^String logger-name ^Level level]}]
(let [level-int (.intValue level)]
(not
(some (fn [{:keys [logger level]}]
(and (.startsWith logger-name logger)
(< level-int (google-json-payload/JUL-levels->int level))))
[{:logger "org.postgresql" :level :config}
{:logger "jdk.event.security" :level :config}
{:logger "okhttp3.internal" :level :config}
{:logger "sun.net.www.protocol.http.HttpURLConnection" :level :config}]))))
:pretty? (nil? (System/getenv "K_REVISION"))}
Like for example here pretty? true
is for developing, so I detect if it is deployed in cloud or non with K_REVISION:db/postgresql {:uri (System/getenv "postgresql")}
In fact all my code use this config later. It is creating pool of connection which I use everywhere.
I mean with Integrant you can not only pass parameters to functions which warm up services, but this functions can also return data which you can and should use later in the app
At least so for I didn’t have to overwrite anything. I just pass right values in main configuration depends on environment.