!!注意!!
dyayaml開発当初はろくなYAMLライブラリが無かったのは確かです。
今はlibyamlという優れたライブラリがありますので、そちらの使用を強く推奨します。
奇遇にもlibyamlはYAMLをストリームとして扱うメインの構造がdyayamlとまるで同じで、移行はとても簡単です。
無いとは思いますが既にdyayamlで作ったデータがあり、dyayamlの勝手な仕様のせいで互換性のないYAMLを抱えてしまっている方は、変換用にdyayaml2libyaml.cを用意しましたので、どうぞお使いください。
くれぐれも、dyayamlからは早々にお離れください。
なんなのなんなの
様々な言語から使えるYAMLのReader&Writerです。
たぶんC, Delphi及びBorland互換Pascal, D言語, Ada、もしかしてHaskellから使えます。
dyayamlはYAMLを破壊する
対応してない構文が多数あります。
○ | 値(Scalar), Sequence, Mappingに対応しています |
× | タイプ(!)は冒頭(---)にのみつけることができます |
× | コメントは冒頭を除き行頭からのみ開始できます |
× | Unordered Set(?)には対応していません |
× | Mapping between sequences(? A : B)が使えません |
○ | Ordered mappings(- A : B)は使えます |
× | Sequence([]), Mapping({})の一行記法が使えません |
○ | 値のliteral style(|)に見かけ上対応しています |
× | 値のfolded style(>)には対応していません |
× | Anchor, Aliasその他雑多な機能には対応していません |
…つまり、Scalar, Sequence, Mappingだけで、木構造を構成することのみできます。
あと細かいところで勝手な仕様を混ぜてますので下手にdyayamlを使うと他のYAMLライブラリで読めなくなるかもしれません。例えばタブをインデントに使うこともできます。
strictなYAMLなんてどうでもよくてそれっぽい構文が使えればそれでいい人向け。
機能面
ライブラリとしての機能は、以下のようなものがあります。
- ストリーム読みこみができます。
- ストリーム書き込みができます。
- コメントも読み書きできます。
- 最大の特徴として、関数内関数を用いて木構造をコード上で再現した読み書きができます。ひとつのルーチンで読み書き両方を行えます。
- downward closure必須なのでC/C++ではたぶん無理。いや、templateの大家様なら実現できるかも。私には無理。
- あまり深くない歴史的経緯によりD言語のみbogoYAML互換インターフェースが残ってたりして専用のデータホルダにツリー構造を格納することができます。
download
Delphiからの使い方
いい加減な説明をします。
まず、Delphiからの場合必要なのはdyayaml_omf.objとdyayaml.pasだけです。あとはポイしてください。makefileも要りません。
dyayaml.pasのimplementationのすぐ後にdyayaml_omf.objをリンクする指令があるのでそこのパスを実際にファイルを置いた位置に書き換えるだけでOKのはずです。
出力はこんな感じです。
{$APPTYPE CONSOLE}
uses
dyayaml;
type
T = record
X, Y: Integer;
end;
var
Writer: TYamlWriter;
Serializer: IYamlSerializer;
X: T;
procedure T_Mapping(Context: Pointer); cdecl;
begin
IO(Serializer, 'x', X.X);
IO(Serializer, 'y', X.Y);
end;
begin
Writer := TYamlWriter.Create('TypeIsT');
Serializer := Writer;
IO(Serializer, T_Mapping, nil);
WriteLn(Writer.Output);
end.
上記コードは次の出力を行います。
--- !TypeIsT x: 0 y: 0
上記コードのままではグローバル変数を介するか、Contextというポインタ型の引数を介するかしないとコールバック関数のT_Mappingに変数を渡せません。ところが、上記コードは何故かこう書き換えることができます。理由は説明しません。
{$APPTYPE CONSOLE}
uses
dyayaml;
function GetContext: Pointer; register;
asm
mov eax, ebp
end;
type
T = record
X, Y: Integer;
end;
procedure IO(Serializer: IYamlSerializer; var X: T); overload;
procedure T_Mapping; cdecl;
begin
IO(Serializer, 'x', X.X);
IO(Serializer, 'y', X.Y);
end;
begin
IO(Serializer, CYamlIOMapping(@T_Mapping), GetContext);
end;
var
Writer: TYamlWriter;
Serializer: IYamlSerializer;
X: T;
begin
Writer := TYamlWriter.Create('TypeIsT');
Serializer := Writer;
IO(Serializer, X);
WriteLn(Writer.Output);
end.
そして、このprocedure IO(Serializer: IYamlSerializer; var X: T); overload;
という関数は、そのまま読み込みにも使うことができます。
いい加減な説明終わり。
リンク
- YAML Ain't Markup Language
- YAMLの本家サイトです。
- bogoYAML
- dyayamlがかなり影響を受けたYAMLライブラリです。D, Javaによる実装があります。
- YSLT
- YAML版XSLT。*1
- Rubyist Magazine - プログラマーのための YAML 入門 (中級編)
- 何故かdyayamlが紹介されています。*2