Fork me on GitHub
#clojure
<
2022-09-09
>
jumar07:09:14

For those of you that use Selmer: how can I check whether a value (variable) is in given set? For example:

{% for status in statuses %}
              {% if selected-status.{{status}} %}checked="checked"{% endif %}
{{status}} denotes the variable that I would like to replace with its value. This almost works, but if tag treats the value literally. If I hardcode status variable value then it gets checked.

walterl08:09:14

Hacky, but working:

(require '[selmer.filters :as f])
(require '[selmer.parser :as p])
(f/add-filter! :get (fn [m k] (get m (keyword k))))
(s/render "[{{ x|get:@k }}]" {:k "y", :x {:y "foo"}})
=> "[foo]"

borkdude09:09:40

Maybe do the filtering before rendering in selmer

jumar09:09:07

Yeah, I ended up restructuring it by making status a map with :selected? key populated on the backend.

mkvlr12:09:04

when calling eval after read , how do I best attach source location information (file, line & col) on the read form so that clojure.main/ex-triage will use it? Should I catch & rethrow with :clojure.error/source?

Alex Miller (Clojure team)12:09:50

Doesn't read do that for you?

mkvlr12:09:54

sorry, I meant after read-string

mkvlr12:09:22

should I set the *file* binding during read-string?

Alex Miller (Clojure team)12:09:48

I think you could do that

Alex Miller (Clojure team)12:09:31

Without looking at code, I don't remember all the env that affects this

mkvlr12:09:03

I've looked through it a bit but not too fluent in reading through the java stuff. Well thank you, imagine you're pretty busy with the conference. Trying to improve the error messages in Clerk before the workshop πŸ™ƒ

flowthing14:09:05

;; An ugly hack. Not sure setting the column number is very useful, anyway.
(defn set-column!
  [^clojure.lang.LineNumberingPushbackReader reader column]
  (when-let [^java.lang.reflect.Field field (.getDeclaredField clojure.lang.LineNumberingPushbackReader "_columnNumber")]
    (-> field (doto (.setAccessible true)) (.set reader column))))

(def reader
  (clojure.lang.LineNumberingPushbackReader. (java.io.StringReader. "(throw (ex-info \"Boom!\" {:a 1}))")))

(set-column! reader (int 42))
(.setLineNumber reader (int 84))

(binding [*file* "/path/to/my.clj"
          *source-path* "my.clj"
          *ns* (the-ns 'user)]
  (eval (read reader)))

(-> *e Throwable->map clojure.main/ex-triage clojure.main/ex-str)
;;=> "Execution error (ExceptionInfo) at user/eval28938 (my.clj:84).\nBoom!\n"

flowthing14:09:05

Alternatively, you can use the eval-file metadata:

Clojure 1.11.1
user=> ^{:clojure.core/eval-file "foo.clj" :line 84} (/ 1 0)
Execution error (ArithmeticException) at user/eval1 (foo.clj:84).
Divide by zero
user=>
`

flowthing14:09:19

But only if you’re evaluating something you can attach metadata to.

flowthing14:09:21

user=> (eval (read-string "^{:clojure.core/eval-file \"foo.clj\" :line 84} (/ 1 0)"))
Execution error (ArithmeticException) at user/eval8 (foo.clj:84).
Divide by zero

borkdude14:09:00

@U5H74UNSF Have you considered using clojure.core/eval-file ?

user=> (eval (with-meta '(/ 1 0) {:clojure.core/eval-file "foo.clj"}))
Execution error (ArithmeticException) at user/eval20 (foo.clj:1).
Divide by zero

borkdude14:09:06

lol, @U4ZDX466T just mentioned it

mkvlr14:09:54

@U4ZDX466T @U04V15CAJ thank you, haven't considered it as I just learned about it from you, just what I needed thanks!

(try
  (eval (with-meta '(/ 1 0) {:line 99 :col 0 :clojure.core/eval-file "/User/mk/foo.clj"}))
  (catch Throwable t
    (clojure.main/ex-triage (Throwable->map t))))

Adam Helins15:09:16

Is there an alternative to https://github.com/stuartsierra/dependency that allows circular deps?

jkxyz16:09:58

Seems like a good overview of graph libraries here: https://github.com/simongray/clojure-graph-resources

hiredman16:09:50

Alternative in what way? That library is explicitly for modeling the dag of clojure namespaces, where the compiler explicitly throws a fit if you have cycles

Adam Helins16:09:59

@UE72GJS7J Thanks! Most linkx are probably way overkill but maybe I'll find what I need @U0NCTKEV8 Well you can use it for any use case that involves a simple dependency scheme. The only trouble is that it throws on circular dependencies because that is indeed not its purpose.

hiredman16:09:52

right, so what features are you actually looking for in an alternative, since you aren't using the library you are asking for alternatives to for its main use case

Adam Helins16:09:02

Ideally, the same kind of API but simply allowing circular deps. Being able to declare a direct dependency between X nodes and then computing transitive deps for any node.

Adam Helins16:09:24

Really just that πŸ˜…

jkxyz17:09:56

That's a graph with directed edges. I don't think you'll find a library with the same API as Stuart's because it's implementing a DAG with the specific purpose of mirroring Clojure namespace dependency graphs. But there are lots of good libraries that will do what you want if you figure out the more general graph terminology

lilactown16:09:21

I have a macro in a shared library that is used in both CLJ and CLJS. The macro calls destructure. When used in CLJS, this ends up emitting a bunch of calls to Java classes (since the function is called during JVM macroexpansion), which the CLJS analyzer complains about since those obviously don't exist in JS/CLJS. To solve this, I'm trying to conditionally use either clojure.core/destructure or cljs.core/destructure using the old (if (:ns &env) ,,,) trick. This works in CLJS, but breaks when used in a CLJ project that doesn't include org.clojure/clojurescript as a dependency with Syntax error (ClassNotFoundException) compiling at ,,, cljs.core At this point I'm trying to figure out how to conditionally require/refer the cljs.core/destructure var only when cljs.core is on the classpath, but I'm open to other options. Anyone know how I ought to solve this?

hiredman16:09:38

(if (:ns &env) ((requiring-resolve cljs.core/destructure) ...) ...)

lilactown16:09:39

requiring-resolve is what i needed. thanks! πŸ˜„

2FO16:09:43

jvm-opts format for deps.edn Hello, If I need to add the following jvm-opts to my deps.edn what would be the correct format and key name?

"-J--add-opens=java.base/java.nio=ALL-UNNAMED"
"-J--add-opens=java.base/sun.nio.ch=ALL-UNNAMED"
I've tried adding them as follows without success:
{:paths ["src"]
 :deps {ring/ring {:mvn/version "1.9.5"}
        datalevin/datalevin {:mvn/version "0.6.17"}
        rum/rum   {:mvn/version "0.12.9" :exclusions
                   [cljsjs/react cljsjs/react-dom]}}
 :jvm/base {:jvm-opts ["-J--add-opens=java.base/java.nio=ALL-UNNAMED"
                       "-J--add-opens=java.base/sun.nio.ch=ALL-UNNAMED"]}}

dpsutton16:09:50

:jvm/base is not a recognized key in deps.edn. You need to put them in an alias {:aliases {:jvm/base {:jvm-opts […]}}} and then use the alias

πŸ™ 1
Alex Miller (Clojure team)17:09:56

the -J prefix is only for the command line, you should not use it in an alias :jvm-opts

πŸ™ 1
Alex Miller (Clojure team)17:09:20

{:paths ["src"]
 :deps {ring/ring {:mvn/version "1.9.5"}
        datalevin/datalevin {:mvn/version "0.6.17"}
        rum/rum   {:mvn/version "0.12.9" :exclusions
                   [cljsjs/react cljsjs/react-dom]}}
 :aliases {:jvm-base
           {:jvm-opts ["--add-opens=java.base/java.nio=ALL-UNNAMED"
                       "--add-opens=java.base/sun.nio.ch=ALL-UNNAMED"]}}}
then clj -A:jvm-base

πŸ™ 1
πŸ‘ 1
2FO17:09:52

Thanks, are the jvm-opts persisted across restarts, or should I run clj -A:jvm-base each time I start the app?

dpsutton17:09:17

jvm options are options passed to the jvm on startup. They are not persisted across restarts

πŸ™ 1
jmckitrick17:09:07

Has anyone found a (clever?) use case for find? I don’t see it often in the wild.

ghadi17:09:15

(if-let [[k v] (some #(find m %) [:key1 :key2 :key3])]
  …))

πŸ‘ 4
borkdude18:09:19

I usually use find if I want to have both the key and the value, or if I want to have a result, even if the value is nil or false

πŸ‘ 2
JohnJ19:09:26

when you want to tell the difference between a key that is associated with nil and a key that is not present

phill22:09:23

@U01KZDMJ411 although (get m k ::some-obscure-default) is more explicit about distinguishing between absence and nil-valued

JohnJ22:09:29

that doesn't play nice with conditionals, ::some-obscure-default value will always be true even if the key is absent

walterl05:09:02

Isn't contains? better for testing key presence, regardless of (falsy) value?

JohnJ21:09:45

yes but if you need to the test and get the value you have to do two map lookups

βž• 1