Как отобразить код clojure в JSON и из него?

У меня есть сумасшедшая идея, которая включает в себя размещение некоторого кода clojure в CouchDB и написание представлений, которые запрашивают его. Я не хочу хранить код clojure как обычный текст, потому что тогда мне придется беспокоиться о его синтаксическом анализе в представлениях. Форматирование и комментарии не нужно сохранять, но код должен иметь возможность входить и выходить из базы данных без изменения структуры. Ключевые слова, символы и строки должны оставаться в своем родном типе. Кроме того, я хочу, чтобы код выглядел элегантно и эффективно.

Я подумываю представить вещи следующим образом:

  • Символы как строки, начинающиеся с '
  • Ключевые слова как строки, начинающиеся с:
  • Строки без изменений, кроме тех случаев, когда они начинаются с' или:, в котором если они экранированы обратной косой чертой.
  • (скобки) как массив
  • [скобки] как массив с «_ []» в качестве первого элемента
  • отображает ({}) как объект
  • устанавливает (# {}) как объект со значениями 1 и включенным "_ # {}".

Приветствуются критика, опыт и идеи.

Редактировать : Вот что произойдет, если я попытаюсь прочитать и написать код JSON с использованием функций json из clojure.contrib:

user> code
((ns bz.json.app (:use (ring.middleware file))) (defn hello [req] {:status 200, :headers {"Content-Type" "text/plain"}, :body "Hello World!"}) (def app (wrap-file hello "public")))
user> (read-json (json-str code))
[["ns" "bz.json.app" ["use" ["ring.middleware" "file"]]] ["defn" "hello" ["req"] {"body" "Hello World!", "headers" {"Content-Type" "text/plain"}, "status" 200}] ["def" "app" ["wrap-file" "hello" "public"]]]

Там нужно немного сделать, чтобы строка 4 вышеперечисленного была точно такой же, как строка 2. Похоже, что это библиотечный проект, если только нет функции, которая выполняет это, о которой я не знаю.

С такой библиотекой ее вызов может выглядеть следующим образом:

user> (= (json-to-code (read-json (json-str (code-to-json code)))) code)
true
22
задан Benjamin Atkin 16 August 2010 в 03:12
поделиться

3 ответа

​​

Как предложил Микера, clojure.contrib.json / write-json преобразует не только примитивные типы, но и Clojure ISeq s и Java Map s, Collection s и Array s также. Это должно охватывать большую часть вашего кода (воспринимаемого как данные), но в случае, если вы хотите написать что-нибудь более интересное, легко расширить средство записи JSON, имитируя исходный код Стюарта Сьерры (см. здесь ):

(defn- write-json-fancy-type [x #^PrintWriter out]
    (write-json-string (str x) out)) ;; or something useful here!

(extend your-namespace.FancyType clojure.contrib.json/Write-JSON
    {:write-json write-json-fancy-type})

Предполагается, что вам не нужно хранить вычисленный байт-код или захваченные замыкания. Это была бы совсем другая игра, значительно сложнее. Но поскольку большую часть кода Clojure (как и большинство Lisp) можно рассматривать как дерево / лес S-выражений , все должно быть в порядке.

Разбор JSON обратно в данные может быть выполнен с помощью clojure.contrib.json / read-json (потратьте немного времени, чтобы ознакомиться с параметрами его определения, возможно, вы захотите их использовать) . После этого eval может стать вашим лучшим другом.

9
ответ дан 29 November 2019 в 05:09
поделиться

Для полноты картины существует также clj-json, который использует Jackson для разбора JSON.

4
ответ дан 29 November 2019 в 05:09
поделиться

Если вы хотите использовать JSON в качестве представления, я настоятельно рекомендую использовать clojure.contrib.json , который уже выполняет работу по преобразованию Преобразуйте структуры данных в JSON довольно легко.

Нет смысла изобретать колесо: -)

Я довольно успешно использовал его в своем текущем проекте Clojure. Если он не делает все, что вы хотите, вы всегда можете внести исправление, чтобы улучшить его!

8
ответ дан 29 November 2019 в 05:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: