Fork me on GitHub
#rewrite-clj
<
2022-01-06
>
cddr15:01:13

So in relation to the problem I described a few days ago, I wrote a function which attempts to determine whether some zloc is in the key position of a map. But I think it only works for the first map entry

(defn map-key?
  [zloc]
  (and
   (zip/map? (zip/up zloc))
   (zip/leftmost? zloc)))
Anyone know how this could be written to match a key in any map entry?

cddr15:01:03

Or maybe it’s better to just identify the containing maps and replace them as a whole?

borkdude16:01:06

@cddr how I approached this in rewrite-edn: I just treated every nth element as a key and every n+1th element as a value

lread16:01:49

@cddr if you need to, you might also want to consider accounting for any #_ that might be present. Example {:a #_ ignored-thing 1}

cddr16:01:29

Oh fortunately I don’t think I’ll need to worry about that but thanks for the headsup

👍 1
yogthos21:01:37

was wondering if anybody could help here, when I do this

(z/sexpr (z/of-string "{:db.sql/connection #profile\n {:prod {:jdbc-url #env JDBC_URL}}}"))
I end up with
#:db.sql{:connection (read-string "#profile\n{:prod {:jdbc-url #env JDBC_URL}}")}
is there a way to roundtrip this properly?

borkdude22:01:54

@yogthos you can do this by (binding [*print-namespace-maps* false] ...) , forgive me the bolded font, it's supposed to be earmuffed.

yogthos14:01:51

ah perfect!

yogthos14:01:51

hmm, I can't find where *print-namespace-maps* is defined though

borkdude14:01:30

in clojure.core :)

borkdude14:01:55

the printing behavior you saw comes from clojure, not from rewrite-clj

yogthos14:01:00

haha I thought it was a rewrite-clj thing

yogthos14:01:15

these are corners of Clojure I haven't explored yet 🙂

yogthos14:01:33

hmm no dice

(binding [*print-namespace-maps* false]
    (z/sexpr (z/of-string "{:db.sql/connection #profile\n {:prod {:jdbc-url #env JDBC_URL}}}")))

yogthos14:01:33

it's this bit that's causing trouble (read-string "#profile\n{:prod {:jdbc-url #env JDBC_URL}}")

borkdude14:01:24

oh what does it say?

yogthos14:01:05

yeah not sure why it ends up getting wrapped with read-string

borkdude14:01:21

I think this is because you cannot convert #profile ..." to an s-expression without letting rewrite-clj know how to resolve that reader tag

borkdude14:01:06

why do you need the s-expressions, perhaps there is a better alternative?

yogthos14:01:56

I just need to inject a piece of edn into a file, so yeah maybe I'm barking up a wrong tree here

yogthos14:01:44

I use a zipper to find the target location, and then do this

(defn edn-merge-value [value]
  (fn [node]
    (if-let [inside-map (z/down node)]
      (-> inside-map
          (z/rightmost)
          (zipper-insert-kw-pairs (z/down value)))
      (z/replace node (z/node (format-zloc value))))))

borkdude14:01:33

I don't see sexpr in there?

borkdude14:01:53

you can use str instead to get back the string instead

borkdude14:01:05

sexpr should really be used with caution

yogthos14:01:15

but using str on a node will give a map containing the zipper

borkdude14:01:39

you first need to do (z/node ...)

borkdude14:01:03

and also z/root ... if you're not at the root of the zipper

yogthos14:01:11

ah ok, this looks like what I'm looking for

(binding [*print-namespace-maps* false]
    (str (z/node (z/of-string "{:db.sql/connection #profile\n {:prod {:jdbc-url #env JDBC_URL}}}"))))

borkdude14:01:15

so (-> zloc z/root z/node str)

yogthos14:01:36

thank you!

borkdude14:01:51

probably the print-namespace-maps binding isnt' necessary here

borkdude14:01:03

as rewrite-clj won't change the node representation

yogthos14:01:13

yeah I think I can drop that now

yogthos14:01:59

now I'll have to go back and check all the places I'm using z/sexpr, I think in most cases I intended to do (-> value z/node str)