@alexmiller Hi, thanks for the update. Yes, just the line at the bottom should read the root value has already been reset back to 42, potentially causing a race condition
instead of the root value has already been reset back to 0, causing a race condition
Good day everyone. I'm writing gui application with cljfx and it works on multimethod. I have the following structure.
(defmulti handle ::event)
(defmethod handle ::analyze (β¦))
(defmethod handle ::try-load-file (β¦))
And I want to catch all the exepctions of my method in a multimethod and show an alert window with exception info. But the first question is how can I do that in general.
It's got to be something like this:
(defmulti handle
(fn [event]
(try (event)
(catch Exception e (str e)))))
Although it doesn't works because event is passed as something evaluated already.A little help?
Or the multimethod can be bad idea in given case. If some correction would be given - it would help a lot
@altjsus I'm not sure what you're trying to do
You want to catch exceptions that your handle methods could throw?
If so, I would do this:
(defn try-handle [...]
(try
(handle ...)
(catch (Exception e) (str e))))
(defmulti handle ::event)
(defmethod handle ::analyze (...))
(defmethod handle ::load-file (...))
And I'd have your callers call try-handle
instead of handle
IMO, you donβt want to throw
or catch
exception in the dispatch fn as it will try to find a dispatch method. Even with your str
it will throw an exception (NullPointerEx)
If you look at MultiFn.java
from clojure source code youβll find :
public Object invoke(Object arg1) {
return getFn(dispatchFn.invoke(arg1)).invoke(Util.ret1(arg1,arg1=null));
}
which means that the dispatchFn
has to find some defmethod
to call invoke
again
Hi, I'm looking for a code-flow visualizer for clojure. Something similar to http://www.pythontutor.com/visualize.html#mode=edithttp://www.pythontutor.com/visualize.html#mode=edit. Any pointers would be much appreciated. Thanks!
@didibus https://github.com/vlaaad/reveal looks relevant
you could have a default value for your dispatch and handle exception on a per-method basis
(defmulti yeahhh (fn [o] o))
(defmethod yeahhh :default [event] (pr "called when no defmethod was found"))
(defmethod yeahhh :a [event]
(try (throw (ex-message "Ex"))
(catch Exception e (str "Handled") )))
(yeahhh :a)
Hum, I don't know of any web based ones, but Emacs, Cursive and I believe VSCode with Calva all have debuggers that allow you to step through code and see the value of every variable and the result of every evaluation as you step through the code
There's some library also that do this a bit more "manual" I think they normally refer to this as tracing, for example https://github.com/clojure/tools.trace
And I remember of https://github.com/dgrnbrg/spyscope and https://github.com/clojure-emacs/sayid
Here's the guide for VSCode with Calva: https://calva.io/debugger/
I'm primarily looking for something web based where I can trace the code flow line by line. The only visualizer I have been able to find so far is a block-visualizer - http://lincoln-b.com/blocks/ I did install Calva just a while ago. Will go through it and will check out the other libraries as well. Thank you!
I don't know of a web based one. Could be an interesting project!
Hum, its not ideal, but since your link supports JavaScript. You can first convert the ClojureScript code to JS with this: http://app.klipse.tech/ and then paste the JS in your python tutor link
Are there anyone who has some experience with cljfx?
I have Clojure code actually. Haven't explored ClojureScript yet.
The #cljfx channel seems active
Good morning Clojurians. I am trying to figure out how to serve static files based on this document: https://cljdoc.org/d/metosin/reitit/0.3.10/doc/ring/static-resources. Here is the code I have
(ns sandbox.main
(:require [reitit.ring :as ring]
[ring.adapter.jetty :as jetty]))
(def app
(ring/ring-handler
(ring/router
["/ping" (constantly {:status 200, :body "pong"})])
(ring/routes
(ring/create-resource-handler {:path "/" :root "public"})
(ring/create-default-handler))))
(defn start []
(jetty/run-jetty #'app {:port 3000, :join? false})
(println "server running in port 3000"))
I have placed an index.html
file under project_root/public
, but I keep getting HTTP/1.1 404 Not Found
What can i be doing wrong? Below is the output, notice that the ping
request gets the pong
reply.
[I] /home/sporty/clojure~> http localhost:3000/ping
HTTP/1.1 200 OK
Content-Length: 4
Date: Thu, 10 Sep 2020 11:14:24 GMT
Server: Jetty(9.4.28.v20200408)
pong
[I] /home/sporty/clojure~> http localhost:3000/index.html
HTTP/1.1 404 Not Found
Content-Length: 0
Date: Thu, 10 Sep 2020 11:14:30 GMT
Server: Jetty(9.4.28.v20200408)
I don't know much about ring, but shouldn't it be project_root/resources/public
?
I tried the following locations:
project_root/public
project_root/resources/public
project_root/src/resources/public
I recently struggled with the arguments to the Compojure equivalent to ring/create-resource-handler
too. I ended up avoiding the issue by not passing arguments. By default, it mounts resources/public
to "/"
. I then put my static files in a subdirectory that gave me the path I wanted.
@timofey.sitnikov I believe it looks for the resource on the classpath
so move your file under project_root/resources/public/
@timofey.sitnikov note also that you're referring to docs for an old version (0.3.10) of Reitit. Docs for the latest version (0.5.5): https://cljdoc.org/d/metosin/reitit/0.5.5/doc/ring/static-resources
OK, got it, deps.edn must include the
resources` directory like so: :paths ["src" "resources"]
, the static files do need to be in the project_root/resources/public
, and the path parameter is required like so (ring/create-resource-handler {:path "/"})
Can someone help me understand the syntax of for
in this toy code example? Why is it that let
binding becomes a keyword :let
:
(for [x (range 1 6)
:let [y (* x x)
z (* x x x)]]
[x y z])
:let is a special modifier understood by for (`for` is a macro and basically has its own syntax)
I mean I understand this is how it just is but curious about why the modifiers turn into keywords if itβs not too esoteric.
Ahh cool.
@rosschapman doseq
supports the same syntax as for
-- with :let
, :when
, :while
Good day. I'm trying to make an uberjar of my project. It runs perfectly with lein run
but, lein uberjar
hangs (> 30 minutes) and lein jar
creates a jar but trying to run like leads to java.lang.ClassNotFoundException
any ideas?
do you have any top level expressions that do lots of work? long running jobs, infinite loops working on queues and such?
I mean: why would it work with 'lein run'?
Guess not
because lein run spins up an interactive long-running process and you want these long running things. if you are compiling you don't want these long running processes.
Hm I will try tomorrow. Thanks for the hint
(def s [ [[:a :b] 'x] [[:c :d] 'y] ])
(mapcat (fn [[l e]] (map #([% e]) l)) s)
I get args(0) passed to PersistentVector?
check (macroexpand '#([% e]))
(fn* [p1__439923#] ([p1__439923# e]))
is the result and its invoking your vector
(macroexpand '#(inc %)) -> (fn* [p1__439927#] (inc p1__439927#))
is macroexpand the right way, did i go about this the wrong way?
looking for
{:a 'x :b 'x :c 'y ...}
no, i'm saying macroexpand will show you what your anonymous function is turning into #([% e])
is a function (fn [thing] ([thing e]))
which is invoking the vector with no args
not related to your logic, but just not doing what you want
thanks, that was confusing, didn't know to try macroexpand
its a common mistake. everyone has gone through that one π
i presume (into {}) is non-lazy?
correct. but there's no way to lazily build a map in any context
maps are a concrete data structure and always fully realized
clojure is a strict language, it is never lazily evaluated (or non-strictly) like say haskell
there are some technicalities to this, lazy-seqs are a strictly constructed lazy data structure, but there is no lazy evaluation
Hello, whats the best way to manage environment variables in deps.edn
project
how do environment variables impact deps.edn?
@vishal.gautam You can set JVM properties in deps.edn
but environment variables are outside the scope of setting up and running a (Clojure) process.
;; if you want to load properties from a file (java style)
(defn load-props [f]
(let [in (io/input-stream f)
updated-props (.load (System/getProperties) in)]
(.close in)
(System/setProperties updated-props)))
(load-props "my.properties")
;; then access the property like,
(System/getenv "a-property-name")
;; System/getenv works with any env var
Environment variables are used directly by the Clojure application. Evaluating (System/getenv)`` will return a map of all environtment variables. The function will also read in a specific environment variable
(System/getenv "PORT")
Use the aero
library to define all configuration in one file, including which environment variables to use across multiple environments, e.g. dev, staging, live
https://github.com/juxt/aeroAs others have mentioned, Java properties files can also be used to configure the Java Virtual Machine https://practicalli.github.io/clojure-webapps/app-servers/java-system-properties.html