У меня есть сумасшедшая идея, которая включает в себя размещение некоторого кода clojure в CouchDB и написание представлений, которые запрашивают его. Я не хочу хранить код clojure как обычный текст, потому что тогда мне придется беспокоиться о его синтаксическом анализе в представлениях. Форматирование и комментарии не нужно сохранять, но код должен иметь возможность входить и выходить из базы данных без изменения структуры. Ключевые слова, символы и строки должны оставаться в своем родном типе. Кроме того, я хочу, чтобы код выглядел элегантно и эффективно.
Я подумываю представить вещи следующим образом:
Приветствуются критика, опыт и идеи.
Редактировать : Вот что произойдет, если я попытаюсь прочитать и написать код 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
Как предложил Микера, 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
может стать вашим лучшим другом.
Для полноты картины существует также clj-json, который использует Jackson для разбора JSON.
Если вы хотите использовать JSON в качестве представления, я настоятельно рекомендую использовать clojure.contrib.json , который уже выполняет работу по преобразованию Преобразуйте структуры данных в JSON довольно легко.
Нет смысла изобретать колесо: -)
Я довольно успешно использовал его в своем текущем проекте Clojure. Если он не делает все, что вы хотите, вы всегда можете внести исправление, чтобы улучшить его!