URI Template draft-03 について考える
URI::Template 0.14_01 は draft-03 相当 - Yet Another Hackadelic を書いた後に deparse が何故出来ないのかなぁと思ってたんだけど、理由を考えたら簡単でした。
その前に URI Template の文法について簡単に説明
draft-03 時点での文法はかなり簡単で、ブレースで囲まれた部分をテンプレートと見なすのが原則です。
ABNF のが分かりやすいですね。
op = 1*ALPHA arg = *(reserved / unreserved / pct-encoded) var = varname [ "=" vardefault ] vars = var [ *("," var) ] varname = (ALPHA / DIGIT)*(ALPHA / DIGIT / "." / "_" / "-" ) vardefault = *(unreserved / pct-encoded) operator = "-" op "|" arg "|" vars expansion = "{" ( var / operator ) "}"
最終的にブレースの中身は "var" or "operator" ですな。
var の例
{foo} {bar=default value}
operator の例
{-join|&|foo,bar} {-list|/|args}
expansion が 0 以上ある訳ですね。
なんで deparse 出来ないのか
まぁ以下の理由とかなのかなと。
変数代入が連続する場合
まず展開 (expansion) で変数代入が連続する場合は不可逆になるのは誰でも思いつきますね。
foo := "a" bar := "b" {foo}{bar} -> "ab"
これを "ab" から foo := "a", bar := "b" と必ずしも導けない。
opt/neg operator の場合
opt は、
foo := "fred" "{-opt|fred@example.org|foo}" -> "fred@example.org" "{-opt|fred@example.org|bar}" -> ""
定義されていれば arg にある値を適用して、無ければ空。Perl で書くなら、
($foo) ? 'fred@example.org' : '';
$foo が真と判定される値ならば何でも "fred@example.org" になるんだから、この値が出てきたとしても $foo がなんと言う値だったかは誰も分からない訳だ。
neg はその逆。
(!$foo) ? 'fred@example.org' : '';
だからまったく同じ事が言える。
今の所の見解
で uri@w3.org ML の URI Templates: done or dead? あたりが draft-03 が出る直前の議論みたい。
ちらっと読んだけど、まだまだ複雑になりそうな雰囲気がするので、暫く放置する。