This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-08-17
Channels
- # announcements (13)
- # beginners (56)
- # brompton (1)
- # cider (2)
- # cljsrn (10)
- # clojure (369)
- # clojure-australia (4)
- # clojure-boston (1)
- # clojure-europe (28)
- # clojure-nl (1)
- # clojure-spec (1)
- # clojure-uk (18)
- # clojurescript (26)
- # data-science (2)
- # datahike (4)
- # datalog (2)
- # datasplash (6)
- # datomic (9)
- # events (1)
- # kaocha (4)
- # macro (1)
- # malli (22)
- # meander (40)
- # membrane (30)
- # music (1)
- # nbb (3)
- # news-and-articles (3)
- # off-topic (12)
- # practicalli (1)
- # re-frame (19)
- # remote-jobs (1)
- # sci (22)
- # shadow-cljs (15)
- # spacemacs (4)
- # tools-deps (40)
- # xtdb (26)
Hey guys, I'm currently working through the D. Sotnikov book 'Web Dev with Clojure, 3rd Ed.' where I package a Luminus webapp as an uberjar and then run it with the JVM. But then I am not sure how to shut down the web server once it's running? I just used ps -A |grep java
and then kill -9
followed by the PID to shut it down but I'm not sure if this is the proper way to shut down a web server. Would this way cause issues with unclean shutdowns particularly with regards to the database connection? I'm not experienced with web dev, just so you know 😅
If it’s running in a terminal, you should be able to stop it with Ctrl-C, which will be how you can stop just about any running process in a terminal.
Well, generally you run uberjars in production. In that environment the proper way to kill a server is to send a shutdown message and then kill the machine
its not guaranteed to run, but you can add shutdown hooks to the jvm that it will run on a best effort basis for cleaning up db connections
Thank you for the answers 🙂
ring.adapter.jetty/run-jetty returns a object with .stop method.
(defonce server (jetty/run-jetty #'router {:port 8000 :join? false}))
(.stop server)
How would I call it do you know?
I think maybe Ctrl + C is all I need to stop the server as I managed to find info on Jetty which said to use Ctrl + C to stop it. Thanks for the info on the .stop method, I'll look into that too 🙂
Hi all, how to just take the value here [{:items 3}]
?
which one? there are many )
[{:items 3}]
, {:items 3}
, :items
and 3
to access deeply nested value there is cool function get-in
keep returns a lazy sequence of the non-nil results of applying function (in your example :items
to each item of collection.
(:items (first [{:items 3}]))
The map {:items 3}
is the first element in the vector and then the keyword :items
can be used as a function call to produce the value associated with it from within the map.
Most Clojure beginner's books have a chapter on destructuring or you can look that up online for info on how you can grab stuff from within nested data structures.
(let [value [{:items 3}]]
(= (get-in [0 :items] value)
(:items (first value))
(first (map :items value))
(:items (nth items 0))))
(val (first [{:items 3}]))
would also work methinks
yes, together with other N different solutions )
That last one misses a level.
val
works on a key/value pair from a map. You usually get these when iterating through a map (i.e. when treating the map as a seq). That can work on the first (and only) entry in the map. However, first
here will return the entire map. You then need to get the first in there. So you can use:
(val (first (first [{:items 3}])))
But getting the first-of-the-first item is a common enough idiom that there is a shortcut function for you: ffirst
(val (ffirst [{:items 3}]))
If extracting deeply nested values, I tend to either use threading macros (since these make the path down to the item clearer to read) or destructuring. So given:
(def the-value [{:items 3}])
Then with a threading macro:
(-> the-value first :items)
Or, if it’s not necessarily in the first position, nth
can be used:
(-> the-value (nth 0) :items)
But I usually want to extract the value into a var, in which case I can destructure for it in a function definition, or a let
block:
(let [[{v :items}] the-value] ...)
or
(defn my-fn [[{:keys [items]}]] ...)
(note that I renamed the items
value in the let
destructuring, and kept the name via :keys
in the second. There is no significance to this)
Neat. Thanks for that elucidation ^.^
Once a value has defined in a namespace by the reader, can that value be undefined, specifically when working within the repl? I understand using comments for testing, however a refactor can lead to changing around values (def/defn) in the namespace.
are you asking if you can undefine it intentionally or if it can become undefined unintentionally?
intentionally
user=> (doc ns-unmap)
-------------------------
clojure.core/ns-unmap
([ns sym])
Removes the mappings for the symbol from the namespace.
user=> (def foo 3)
#'user/foo
user=> foo
3
user=> (ns-unmap *ns* 'foo)
nil
user=> foo
Syntax error compiling at (REPL:3:1).
Unable to resolve symbol: foo in this context
namespaces are essentially mutable (ouch, it hurts) maps of names to vars
The calva extension to VScode continues to see the variables as read by the reader, previously, even though the variables have been manually been changed, intentionally
variable hints and similar features require me to stop the repl after time
the calva tooling is running inside of your program. it doesn't look at the text file really but introspects the namespaces themselves. so if it is still defined in the ns it will offer it as a suggestion
understandable as to how/why and it's appreciated. but can become somewhat cumbersome after a week or so of significant changes
If you need to clean-up a namespace, you can try something like this:
(map (partial ns-unmap *ns*) (ns-map *ns*))
what does that do to external namespaces with an existing dependency?
We might be able to fix it, @franco.gasperino Chime in on thia issue: https://github.com/BetterThanTomorrow/calva/issues/1260
Any core approach to perform the following?
(defn assoc-in* [m ks]
(reduce
(fn [l r]
(let [x (- (count r) 1)]
(assoc-in l (subvec r 0 x) (nth r x)))) m ks))
=> (def orig {:a {:b {:c 1 :d 2}}})
=> (assoc-in* orig [[:a :b :d 3]])
{:a {:b {:c 1, :d 3}}}
=> (assoc-in* orig [[:a :b :e 4]])
{:a {:b {:c 1, :d 2, :e 4}}}
=> (assoc-in* orig [[:aa 1] [:a :b :c {:cc 1}]])
{:a {:b {:c {:cc 1}, :d 2}}, :aa 1}
your first two examples are very close to regular assoc-in already:
(assoc-in origin [:a :b :d] 3)
also, you can replace (subvec r 0 x)
with (pop r)
and (nth r x)
with (peek r)
The last example is why i'm curious. I have a use case where i want to update 3+ nested map values, and this occurs in several different locations
and not relevant to the question presented, but I'd move m and ks to a new line (or a new line each) as they belong to a lower indentation than the start of the line they are on
reduce
seems a fine way to do it, in that case.
And yeah, @U051SS2EU’s advice about the whitespace is good. I thought you made a mistake with reduce, initially.
thanks for the tip. i hadn't read that pop and peek were collection dependent behavior
(defn assoc-in* [m ks]
(reduce #(assoc-in %1 (pop %2) (peek %2)) m ks))
Much more terseanother random code-review type thing, in clojure.core, foo*
is always a lower level thing that's used to implement foo
, so you might want to use some other differentiating suffix
acknowledged
Can I use the clojure
command to only download the project dependencies? I.e. not run the project or drop me into a REPL prompt.
from clojure --help
:
> -P Prepare deps - download libs, cache classpath, but don't exec
Thanks, I actually didn’t see it in the help. We should create a https://github.com/tldr-pages/tldr page for it. 😃 (Not joking, actually, just looks friendlier with a smiley 😂 )
OK. So now I understand why I didn’t see it. On the machine I checked it first it wasn’t there. It has version 1.10.1.536
. Thing is, clojure is freshly installed. Even if I upgrade I get this:
gitpod /workspace/pirate-lang $ brew upgrade clojure/tools/clojure
Warning: clojure/tools/clojure 1.10.1.536 already installed
I guess I should bring this up with the Gitpod peeps…