Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在JSON之间映射clojure代码?_Json_Clojure_Lisp_Couchdb - Fatal编程技术网

如何在JSON之间映射clojure代码?

如何在JSON之间映射clojure代码?,json,clojure,lisp,couchdb,Json,Clojure,Lisp,Couchdb,我有一个疯狂的想法,它涉及到将一些clojure代码放入CouchDB并编写查询它的视图。我不想将clojure代码存储为纯文本,因为这样我就不得不担心在视图中解析它。格式和注释不需要保留,但是代码应该能够在不改变结构的情况下进出数据库。关键字、符号和字符串都应保持其本机类型。此外,我希望代码看起来优雅高效 我想把事情表现如下: 以' 以以下字符串开头的关键字: 字符串未经修改,除非它们以“或:”开头,在这种情况下,它们用反斜杠转义 (parens)作为数组 [括号]作为第一个元素为“[]”的

我有一个疯狂的想法,它涉及到将一些clojure代码放入CouchDB并编写查询它的视图。我不想将clojure代码存储为纯文本,因为这样我就不得不担心在视图中解析它。格式和注释不需要保留,但是代码应该能够在不改变结构的情况下进出数据库。关键字、符号和字符串都应保持其本机类型。此外,我希望代码看起来优雅高效

我想把事情表现如下:

  • 以'
  • 以以下字符串开头的关键字:
  • 字符串未经修改,除非它们以“或:”开头,在这种情况下,它们用反斜杠转义
  • (parens)作为数组
  • [括号]作为第一个元素为“[]”的数组
  • 将({})映射为对象
  • 将(#{})设置为对象,其值设置为1并包含“#{}”
评论、经验和想法受到赞赏

编辑:如果我尝试使用clojure.contrib中的JSON函数读写JSON代码,会发生以下情况:

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

如果您想使用JSON作为表示,我强烈建议使用,它已经完成了将Clojure数据结构无缝转换为JSON的工作

没有必要重新发明轮子:-)

我在当前的Clojure项目中非常成功地使用了它。如果它不能做到你想要的一切,那么你可以随时贡献一个补丁来改进它

正如mikera所建议的,/write json不仅会转换原始类型,还会转换Clojure的
ISeq
s和Java的
Map
s、
Collection
s和
Array
s。这应该涵盖您的大部分代码(视为数据),但如果您想编写更高级的代码,可以通过模仿Stuart Sierra的源代码来扩展JSON编写器(请参阅):

这是假设您不需要存储计算字节码或捕获的闭包。这将是一场完全不同的游戏,难度要大得多。但是,由于大多数Clojure代码(像大多数Lisp代码一样)都可以被视为一棵树/森林,所以您应该可以


可以使用
clojure.contrib.JSON/read JSON
将JSON解析回数据(花一点时间查看其定义上的选项,您可能需要使用它们)。在那之后,
eval
可能是你最好的朋友。

为了完整起见,还有一个在下面使用Jackson解析JSON的工具。

对于clojure.data.JSON的0.1.2版,我想整个事情可能是这样的:

(require ['clojure.data.json :as 'json])

(defn- json-write-date [s ^java.io.PrintWriter out escape-unicode?]
  (.write out (str "\""
    (.format (java.text.SimpleDateFormat. "yyyyMMddHHmmssZ") s)  "\"")))

(extend java.util.Date clojure.data.json/Write-JSON {:write-json json-write-date})

(json/json-str { :example (java.util.Date.)})
"{\"example\":\"20120318182612+0100\"}"`

我认为你的想法是正确的,但我会通过使用标记数组(
[“list”,…]
[“vector”,…]
)来简化集合的处理。除此之外,我不会改变实施策略

我喜欢你的想法,也喜欢用Clojure编写代码,所以我尝试了一下将你的
代码实现为json
(结合上述建议)在

这是它生成的输出:

(code-to-json example-code)
; => ["list" ["list" "'ns" "'bz.json.app" ["list" ":use" ["list" "'ring.middleware" "'file"]]] ["list" "'defn" "'hello" ["vector" "'req"] {":status" 200, ":headers" {"Content-Type" "text/plain"}, ":body" "Hello World!"}] ["list" "'def" "'app" ["list" "'wrap-file" "'hello" "public"]]]

json-to-code
留给读者作为练习

clojure.contrib.json
已被以下内容取代:

您可能还想使用它,它有一个很好的API,并支持各种扩展,如自定义编码和SMILE(二进制JSON):


我不打算为json编写解析器,所以我可能会使用clojure.contrib.json。我正在寻找一种方法,将任意clojure代码映射到一个足够简单的数据结构中,并从中无损地转换为JSON。我想将这个问题标记为已回答,但到目前为止的答案确实没有涵盖它!我正在寻找一个示例,说明如何反序列化为JSON,同时保留Clojure读者理解的类型。这需要元数据。如果您只是在为Clojure寻找基本的JSON序列化程序/反序列化程序,那么很抱歉您会看到此页面。这不是这个问题的重点。这实际上不起作用,因为“编写json字符串”是一个私有函数。您可以做的是:(defn-write json奇特类型[x#^PrintWriter out](.print out(json str(str x)))确切地说,它是一个私有函数,应该定义它来编写一些有用的东西,比如您提到的.print。我指的不是库中的某个特定函数-很抱歉,最终会出现误导。我希望您注意细节。:)对我来说似乎很健壮。
(code-to-json example-code)
; => ["list" ["list" "'ns" "'bz.json.app" ["list" ":use" ["list" "'ring.middleware" "'file"]]] ["list" "'defn" "'hello" ["vector" "'req"] {":status" 200, ":headers" {"Content-Type" "text/plain"}, ":body" "Hello World!"}] ["list" "'def" "'app" ["list" "'wrap-file" "'hello" "public"]]]
(require '[clojure.data.json :as json])

(json/write-str {:a 1 :b 2})
;;=> "{\"a\":1,\"b\":2}"

(json/read-str "{\"a\":1,\"b\":2}")
;;=> {"a" 1, "b" 2}
(:require [cheshire.core :as json])

(json/encode {:a 1 :b 2})
;;=> "{\"a\":1,\"b\":2}"

(json/decode "{\"a\":1,\"b\":2}")
;;=> {"a" 1, "b" 2}