外部用語の形式

プログラムがErlangsサーバーにデータを転送する必要がある場合、このデータを最初にシリアル化する必要があります。 つまり、それらはバイナリ形式に変換されるため、アーランはそれらをアンパックできます。 これは通常、ASN.1、google protobuf、thriftなどを使用して行われます。 これらはすべて、間違いなく価値のある製品です。



または、Erlang外部用語形式の使用を検討してください。 Erlang実行可能システムには、2つの関数、 term_to_binary()およびbinary_to_term()があります。これらの関数は、任意の値をこの形式にすばやく効率的にパック/アンパックできます。 erl_ext_dist.html



どのように機能しますか?





内線 その構造のフォーマットは非常に単純です。 通常、その中のデータの形式は「タグ、データ」または「タグ、長さ、データ」です。 タグは、どのタイプのデータがパックされるかを記述します。



基本的なデータ型の場合、タグは







すべてのパックデータの前にタグ131を付ける必要があります。これは、現在のextのバージョン番号です。 用語の形式。



つまり、Erlang値[{banknote、100、rub}]は構造にパックされます:







概念実証として、たとえば、Pythonでext用語形式でpython構造をパックし、erlangで結果をアンパックする簡単な手順を記述します...



PythonリストをErlangリストに、PythonタプルをErlangタプルに、整数、Python行をパックします。 原子の場合...まあ...たとえば、Pythonの文字列から相続人を作成して、パッケージング手順で通常の文字列と簡単に区別できるようにします。



次のようになります:



from types import IntType, StringType, TupleType, ListType from struct import pack import socket class atom(str): pass def _eterm(x,accum): if type(x) is IntType: accum.append(pack('>Bi',98,x)) return if type(x) is StringType: accum.append(pack(">BH",107,len(x))) accum.append(x) return if type(x) is TupleType: accum.append(pack("BB",104,len(x))) for term in x: _eterm(term,accum) return if type(x) is ListType: accum.append(pack(">BI",108,len(x))) for term in x:_eterm(term,accum) accum.append(chr(106)) return if isinstance(x,atom): accum.append(pack("BB",115,len(x))) accum.append(x) return raise AssertionError("Cannot convert that type to erlang term %s"%(x)) def binary(X): accum = [chr(131)] _eterm(X,accum) return "".join(accum)
      
      







素晴らしい。 次に、ある種の複雑な構造をまとめて、最も簡単な方法でアーランに転送します。



 pterm = (atom("vcard"),[(atom("firstname"),"Odobenus"), (atom("lastname"),"Rosmarus"), (atom("age"),48), (atom("children"),[ ("Dimon",1988), ("Natashka",1990), ("Katka",2000), ("Anka",2003)] ) erlterm = binary(pterm) sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.sendto(erlterm,("localhost",10000))
      
      







つまり、彼らはudpパッケージをパックして送信しました。 Erlangでは、以下を受け入れて解読します。



 1> gen_udp:open(10000,[binary]). {ok,#Port<0.585>} 2> R=receive {udp,_ ,_,_,Bin} -> Bin end. <<131,104,2,115,5,118,99,97,114,100,108,0,0,0,4,104,2,115, 9,102,105,114,115,116,110,97,109,101,107,...>> 3> binary_to_term( R ). {vcard,[{firstname,"Odobenus"}, {lastname,"Rosmarus"}, {age,48}, {children,[{"Dimon",1988}, {"Natashka",1990}, {"Katka",2000}, {"Anka",2003}]}]}
      
      







結論




私たちは(少し血で)pythonからアーランまで複雑な構造を渡しました。 このアプローチの利点は



extの欠点。 用語形式:柔軟性には裏返しがあります。 曲がった手や愚かなプログラミングの場合、Erlangサーバーが何をすべきかを知らないだけの構造を詰めることができます。



記事の外では、倍精度数、無次元整数、圧縮データの転送、この形式へのバイナリのパッケージ化などの形式が残っていました。 など しかし、これらはすべてドキュメントに詳しく説明されています。



主なことは、アイデアを理解することです。



All Articles