In article <20090907091830.2C7A.A69D9226 / jp.fujitsu.com>,
  KOSAKI Motohiro <kosaki.motohiro / jp.fujitsu.com> writes:

> APIとしての筋の良さとは別立てとして、javascriptでencode or decodeするので
> まったく同じ使用のencocde/decode関数がRubyにもあるとうれしい。
> というのはあるかも

encodeURI の出力から、入力を得るには、無差別に %-encoding を
解けばいいので、decodeURI でなくてもいいんじゃないでしょうか。
decodeURIComponent でもいいですし、CGI.unescape でもかまいま
せん。

decodeURI は、encodeURI が生成する %-encoding はすべて解きま
すが、そうでない %-encoding を一部解かないことがあるようです
が、これは何の役に立つのかなぁ?
(例えば、decodeURI("%40") が "%40" になるとか。)

> あと、encodeURIComponent()は、その名の通りURIの個々のコンポーネントを
> 引数に取る事を念頭においた関数で、javascriptではString型しかないから、
> URIをコンポーネントに分割する責務を利用者に投げている。
> URI型を作るなら、もうちょっとインテリジェントにやって欲しいという気もしなくはないかも。
> よく知らないけど、URI.split()があるからには、URIの構造をしってるクラスなんですよね?この人。

encodeURIComponent は基本的な考え方としては悪くないと思いま
す。! などがそのままなのは甘いと思いますが、古い RFC の影響
でしょうね。今だったら unreserved 以外を一律に %-encoding に
してしまうのがいいでしょう。

URI クラスが URI の構造を知っているのはそのとおりなんですが、
問題は URI の意味がいろいろと文脈依存なところですね。

たとえば、HTTP URI の query の意味は、受け取る web
application の動作に依存します。たとえば、& と %26 を同一視
していいか、そうでないのかは、web application の動作次第です。

そういうわけで、URI クラスには、& と %26 を区別して指定でき
る API が必要です。そういう API として、文字列の "&" と
"%26" を受け渡すものが使われているというのが現状でしょう。
つまり、エスケープ済みのものを渡す、ということです。

インテリジェント、というのをアプリケーション側でエスケープし
なくてよい、と読みかえると、何をエスケープすべきかというとこ
ろをどこかで補完してあげないといけません。

たとえば、URI.escape_component というのを考えて、コンポーネ
ントとしてエスケープするというメソッドとすると、区切り文字に
なりうる文字をぜんぶエスケープすることになります。
(URI に入れられない文字もエスケープしないといけないので、結
局 unreserved 以外をエスケープするのが適切でしょうが)

あるいは、URI.escape_html_form([[k1, v1], [k2, v2], ...]) と
いうメソッドが、application/x-www-form-urlencoded に従って
(エスケープして) k1=v1&k2=v2&... という形式を生成するメソッ
ドだとすると、k, v の中では、query に使えない文字と =, & を
エスケープすることになります。(あと + と ; もかな)

URI.escape_component にしても URI.escape_html_form にしても、
メソッド名が何をエスケープすべきかというという意味を指定して
いて、どういう API にせよこれと同等な指定はどこかでしないと
いけないわけです。なので、そういう指定をどのくらい簡潔にでき
るかがインテリジェントに思える API の鍵でしょうか。
-- 
[田中 哲][たなか あきら][Tanaka Akira]