1

I am using clojure library to read the edn file Now my data.edn file looks like this.

{:mysites {:locations ["priorityLoc1" "priorityLoc2" "priorityLoc3"]
           :back-up ["backup1uri" "backup2uri"]}
}

Now when i use edn/read the map that get returns looks like

{:mysites {:locations ["priorityLoc2" "priorityLoc1" "priorityLoc3"]
           :back-up ["backup1uri" "backup2uri"]}
}

As you see above in the sequence locations, the positions of the values ie., priorityLoc2 and priorityLoc1 changes. This causes problem with the applications which looks for site locations in order of the sequence as priority. I am not sure why the order gets changed during edn/read , Is there a way I can make sure the order of the sequence is not changed ??

I tried the edn/read as is shown in the documentation page for edn/read https://clojuredocs.org/clojure.edn/read

(defn load-edn
  "Load edn from an io/reader source (filename or io/resource)."
  [source]
  (try
    (with-open [r (io/reader source)]
      (edn/read (java.io.PushbackReader. r)))

    (catch java.io.IOException e
      (printf "Couldn't open '%s': %s\n" source (.getMessage e)))))
    (catch RuntimeException e
      (printf "Error parsing edn file '%s': %s\n" source (.getMessage e)))))))

UPDATE:

I am able to see that edn/read is changing the order when i pass my data edn file , I am trying to replicate the issue with a smaller data file as I cant share my data.edn file here. With my smaller data file the issue is not reproducible.

So, I am not really sure to assume edn/read IS NOT changing the order , is there any chance that edn tries to attempt a sort (like sort by names ?) which causes order to change. Is there a way to make sure order does not change. Below is the code for the edn reader.

(require '[clojure.java.io :as io])
(require '[clojure.tools.reader.edn :as edn])
(require '[clojure.tools.reader.reader-types :as readers])

(defn meine-edn-reader
  "Load edn from an io/reader source (filename or io/resource)."
  [source]
  (try
    (with-open [reader (io/reader source)]
      (-> reader
        readers/push-back-reader
        readers/indexing-push-back-reader
        edn/read))

    (catch java.io.IOException e
      (printf "Couldn't open '%s': %s\n" source (.getMessage e)))))
  • 2
    The example as you show it will _not_ change the order inside a vector. Please provide an minimal failing example that shows that problem. Also how is this related to [clojure.spec]? – cfrick Mar 18 '21 at 07:23
  • are you sure you have a vector (and not a set) in your edn file? – erdos Mar 18 '21 at 09:14
  • @cfrick I am trying to read the edn file using the edn/read from ns [clojure.tools.reader.edn :as edn] and using readers [clojure.tools.reader.reader-types :as readers] . The result of the edn/read is still the same that does not retain the order everytime. I even tried using the IndexPushBackReader (with-open [reader (io/reader input)] (-> reader readers/push-back-reader readers/indexing-push-back-reader edn/read))) The issue is intermittent which makes it difficult to reproduce but it appears often. – developerAtHeart Mar 18 '21 at 10:44
  • @erdos Yes, thats a vector. the file looks something like this {:mysites {:locations ["priorityLoc1" "priorityLoc2" "priorityLoc3"] :back-up ["backup1uri" "backup2uri"]} } – developerAtHeart Mar 18 '21 at 10:50
  • 1
    I suspect something's going on that's not in the original post. You can demonstrate the problem (or not) in a program of about 10 lines including the input EDN string. Please post a complete failing example. – Biped Phill Mar 18 '21 at 15:41
  • Please edit the question with your insights. Also add the code, that shows the problem. I am very confident, the problem is not related to the used reader. I'd rather expect use of unordered containers or just some totally unrelated bug. Assume, that EDN is *not* broken and if you expect it to be, check the tickets for the versions you are using - a problem like this would give a massive outcry. – cfrick Mar 18 '21 at 17:36
  • Thank you for the updated question. I notice something slightly odd in the definition of `meine-edn-reader`, as it is wrapping a `PushbackReader` with an `IndexingPushbackReader`, the latter is sufficient. I have no clue if this is causing the problem at hand though. `(-> reader readers/indexing-push-back-reader edn/read))` will do what you need. – Steffan Westcott Mar 19 '21 at 11:19

0 Answers0