edn:拡張可能なデータ表記

この記事では、ednについて説明します。 ednは、clojureから派生したデータ形式です。 JSONに似ていますが、JSONにはない機能がいくつかあります。 ednの機能は次のとおりです。 シードの例:



{:name "edn" :implementations #{"clojure" "java" "ruby" "python" "c" "javascript" "haskell" "erlang"} :related "clojure" :encoding :UTF-8}
      
      







外観


ednの歴史はJSONの外観に似ています。最初にプログラミング言語が登場し、次にそれからサブセットが抽出され、データ形式として使用され始めました。 JSONの場合、前駆言語はJavaScriptであり、ednの場合はClojureです。



前述したように、ednとJSONは非常に似ており、JSONが最も有名でシンプルで人気のあるデータ形式であることを考慮して、JSONとの違いを通してednについて説明します。



Ednは、JSONに存在するすべての単純なタイプ(文字列、数値、ブール値)をサポートしています。 新しいものもあります:



なし


Ednは、 nil



値をnil



値として使用します。 JSONはnull



使用しnull







キャラクター


ednは、個々の文字を指定するための文字をサポートしています。 バックスラッシュで始まる: \e



\d



\n



。 UTF8: \u2603



形式を使用できます。 特殊文字は、 \return



\newline



\return



\space



\tab



で完全に記述され\tab





JSONでは、通常、個々の文字は長さ1の文字列として表されます。

ednには別の種類のシンボルがあるため、サインシンボルは呼び出しません。これについては以下で説明します。



キーキャラクター


キーシンボルが何であるかを定式化することは困難です。 列挙行が混在していると思います。 それらは、可能な値の有限の固定セットがある場合に便利に使用されます。 これらの値はキーワードで設定できます。 キー文字を表示キーとして使用することも習慣的です。 キー文字はコロン:: :name



:lastname



:female



:lastname



:green



始まります。 ルビーを扱った人は、その中の文字を認識する必要があります;同様のタイプは、一般的なLispなど、他の言語にも存在します。



表示でキーワードを使用し、JSONバージョンと比較する例:



edn ジョンソン
 {:name "Jack" :lastname "Brown" :gender :male}
      
      





 {"name": "Jack", "lastname": "Brown", "gender": "male"}
      
      









数字


ednは、整数と実数の2種類の数値を分割します。 また、整数のサフィックスN



と実数のM



を使用して、任意の長さの数値をサポートします。



 [12345678891231231231232133N, 123.123123123123123213213M]
      
      







ベクトルの


edson JSON配列はベクターと呼ばれます:ランダムアクセス操作がサポートされる値のシーケンス。 JSONとは異なり、要素はコンマで区切らないでください。 それらは省略できます:



 [1 2 3 "Hello" "World"]
      
      







表示(マップ)


JSONでは、オブジェクトと呼ばれます。 ednでは、値のキーはコロンで区切られていません(コロンはエラーです)。 コンマも省略できます。 キーは、数字やキーワードなど、他のタイプでもかまいません。



 {:name "Jack" :lastname "Brown" :gender :male 42 54}
      
      







ここで、キー:name



:lastname



:gender



および42



使用したマッピング42



、値はそれぞれ"Jack"



"Brown"



:lastname



:male



54



です。



多くの


ednはデータ型セットをサポートします。 #{val1 val2 val3}



形式で指定されます。 セット内の順序は重要ではなく、パーサーは特定の順序を保証しません。 原則として、パーサーはプログラミング言語の標準型、たとえばJavaのHashSet



、clojureのPersistentHashSet



などの言語に変換する必要があります。 そして、これらのデータ型では、順序は保証されません。 例:季節と3色を含む非常に便利なディスプレイを設定します。



 {:seasons #{:winter :spring :summer :autumn} :colors #{[255 0 0] [0 255 0] [0 0 255]}}
      
      







リスト


ednは、ベクターに加えてリストをサポートします。 このリストは、ランダムアクセスがないという点でベクターとは異なります。 これはすでにパーサーのビジネスですが、実際の型はリストを変換します。 一般に、ベクトルではなくリストを使用する方が便利な場合を考えるのは困難です。 そのため、ほとんどの場合にベクターが使用されます。 リストの例:



 (1 2 3 4 5)
      
      







シンボル


clojureでは、文字は変数を示すために使用されます。 つまり 通常のプログラミング言語の識別子と同様: a



b



i



hello



persons



。 複数の単語の記号は通常、ハイフンで区切られます: prime-numbers



visited-nodes



。 数字と文字に加えて、次の文字を含めることができます。 . * + ! - _ ? $ % & =



. * + ! - _ ? $ % & =



。 行とキー文字があるときにednで文字を使用する方法を考えるのは難しいです。 すでにあなたの想像力にかかっています。 datomicでは、リクエストを送信するために使用されます。例:



 [:find ?x :where [?x :foo]]
      
      



?x



は文字です。



タグ付き要素


ednは、タグで拡張する機能をサポートしています。 タグは、 #



で始まり、その後に記号が続く識別子です: #myapp/Person



#uuid



#myapp/Person



#uuid



#myapp/Person



。 このような要素の特性は、パーサーがそのような要素に遭遇すると、その要素とそれに続く要素を読み取り、それを特別なハンドラーに渡します。ハンドラーは、入力引数を目的の型に変換して返す必要があります。 例:



 #myapp/Person {:first "Fred" :last "Mertz"}
      
      





ここで、 #myapp/Person



タグのハンドラーはパーサーに登録する必要があります。パーサーはマッピングを受け入れ、 myapp.Person



クラス(言語にクラスがある場合)または同様のオブジェクトに変換します。



 #inst "1985-04-12T23:20:50.52Z"
      
      





ハンドラーは、 RFC-3339形式の文字列を受け取り、対応する日付に変換します。



 #uuid "f81d4fae-7dec-11d0-a765-00a0c91e6bf6"
      
      





ハンドラーは、UUID文字列を対応するオブジェクトに変換します。



最後の2つのタグはインラインであり、そのまま使用できます。 #myapp/Person



場合のように、ユーザータグは常に先頭に名前空間を持たなければならないという制限もあります。ここでmyapp



は名前空間です。 名前空間のないタグ(例: #inst



#uuid



)は、標準ハンドラー用に予約されています。



コメント


コメントを使用するには;



。 それを使用して、次の行をコメントアウトできます。

 { :red [255 0 0] ; Red 255, green 0, blue 0 :orange [255 127 0] ; Red 255, green 127, blue 0 }
      
      





ednのより完全な例


以下は、過去数日間にリソースにアクセスしたすべてのユーザーのリストの例です。 例が考案されており、その目的はednを再度実証することです。



 [{:name "Jack" :lastname "Brown" :roles #{:admin :operator} :last-visited #inst "2013-04-12T23:20:50.52Z" :id #uuid "f81d4fae-7dec-11d0-a765-00a0c91e6bf6"} {:name "John" :lastname "Black" :roles #{:user} :last-visited #inst "2013-04-12T20:20:50.52Z" :id #uuid "b371b600-b175-11e2-9e96-0800200c9a66"}]
      
      







使用する場合


これは主観的な質問です。 上記の機能はすべて、独自の構成を導入することでJSONに実装できますが、これにはJSONとの間で変換するためのより複雑なロジックが必要です。 ednでは、それらは箱から出してすぐに使用できます。これは非常に便利です。 clojureを使用する場合、ednが自然な選択です。 また、退屈なJSONにうんざりしている可能性があり、より柔軟でカスタムのフォーマットを使用したい場合は、タグが役立ちます。 日付に「標準」タイプを使用することも便利な機能です。 ednはステロイドのJSONであると言えます。



参照資料


公式フォーマットの説明: github.com/edn-format/edn

java、ruby、python、javascript、haskellおよびその他の言語の実装github.com/edn-format/edn/wiki/Implementations

Hacker Newsに関するディスカッション: news.ycombinator.com/item?id=4487462彼らは「JSONがあるのになぜ編集されたのか?」



All Articles