書泉で本を 2000円ほど買ったら、スクラッチカードを 2枚くれた。 当たると 50円のサービス券としてつかえるらしい。 削ってみると両方当たりであった。
... えーと、もしかして、ぜんぶ当たりとか?
(逆)ポーランド記法というものがある。
中国人の剰余定理というものがある。
最近、the four Russians' algorithm (4人のロシア人のアルゴリズム) というものがあることを知った。
国の名前がついたものは他に何があるだろうか?
なんとなく買ったまんがの折込広告に、R.O.D 10巻が発売中だと書いてあった。
え、と思って本屋に寄ったが見当たらない。
えーと、スーパーダッシュ文庫は何日発売だったっけか、 と調べてみると、23日なのでまだ発売日前なのであった。
まんがの発売日を調べると、16日だった模様。 ふむ。
まだ前日だが出ていたので買う。
即座に読み... うぅむ、元ネタ集を作る人が何人も出そう。
そういえば、R.O.D に入っていた折込広告は件の折込広告と同じものであった。
%XX の形の escape を行なうメソッドは標準で少なくとも次のものがある。
CGI.escape, URI.escape, WEBrick::HTTPUtils.escape, WEBrick::HTTPUtils.escape_form, ERB::Util#url_encode
これらの違いを調べてみる。
% ruby -rcgi -ruri -rwebrick/httputils -rerb -e ' module ERB::Util module_function :url_encode end table = [] (0..255).each {|c| s = [c].pack("C") e = [ ERB::Util.url_encode(s), CGI.escape(s), WEBrick::HTTPUtils.escape_form(s), WEBrick::HTTPUtils.escape(s), URI.escape(s) ] next if e.uniq.length == 1 p e table << e } p table.transpose.uniq.length ' ["%20", "+", "+", " ", "%20"] ["%21", "%21", "!", "!", "!"] ["%24", "%24", "%24", "$", "$"] ["%26", "%26", "%26", "&", "&"] ["%27", "%27", "'", "'", "'"] ["%28", "%28", "(", "(", "("] ["%29", "%29", ")", ")", ")"] ["%2A", "%2A", "*", "*", "*"] ["%2B", "%2B", "%2B", "+", "+"] ["%2C", "%2C", "%2C", ",", ","] ["%2F", "%2F", "%2F", "/", "/"] ["%3A", "%3A", "%3A", ":", ":"] ["%3B", "%3B", "%3B", ";", ";"] ["%3D", "%3D", "%3D", "=", "="] ["%3F", "%3F", "%3F", "?", "?"] ["%40", "%40", "%40", "@", "@"] ["%5B", "%5B", "%5B", "%5B", "["] ["%5D", "%5D", "%5D", "%5D", "]"] ["%7E", "%7E", "~", "~", "~"] 5
完全に同じのはひとつとして無いらしい。
並べ変えて、RFC 2396 に従って分類してみる。
space: ["%20", "+", "+", " ", "%20"] mark の一部: ["%21", "%21", "!", "!", "!"] ["%27", "%27", "'", "'", "'"] ["%28", "%28", "(", "(", "("] ["%29", "%29", ")", ")", ")"] ["%2A", "%2A", "*", "*", "*"] ["%7E", "%7E", "~", "~", "~"] reserved: ["%24", "%24", "%24", "$", "$"] ["%26", "%26", "%26", "&", "&"] ["%2B", "%2B", "%2B", "+", "+"] ["%2C", "%2C", "%2C", ",", ","] ["%2F", "%2F", "%2F", "/", "/"] ["%3A", "%3A", "%3A", ":", ":"] ["%3B", "%3B", "%3B", ";", ";"] ["%3D", "%3D", "%3D", "=", "="] ["%3F", "%3F", "%3F", "?", "?"] ["%40", "%40", "%40", "@", "@"] unwise の一部: ["%5B", "%5B", "%5B", "%5B", "["] ["%5D", "%5D", "%5D", "%5D", "]"]
space が %20 と + のどちらになるか、という違いは RFC 2396 と HTML form 用 application/x-www-form-urlencoded の違いとして理解できる。
一般に reserved は delimiter に使われるため、 reserved を %XX にするかどうかという違いは、 そのような delimiter で区切られた構造を破壊しない変換であるか、 そのような delimiter で区切る内部のデータを生成する変換であるかの違いとして理解できる。
+ は form のパラメータのエンコードに使うため、 delimiter 内部のデータ生成が用途として想定されているはずである。 そのため、+ を生成するものは reserved を %XX にするはずで、 確認すると確かにそうなっている。
さて、mark と unwise の一部を %XX にするかどうかの違いはどういう意図に基づくものか?
ところで、構造を破壊しない変換というのは、 内部データとして delimiter に使われる文字が現われないという仮定が必要なのであまり正しいやりかたではない。 まぁ、日本語部分を escape したいときくらいには使えてしまうので現実的といえばそうなんだけど、 そういう現実からは目を背けて正しくないのを除くと、残りは ERB::Util#url_encode, CGI.escape, WEBrick::HTTPUtils.escape_form になる。 後者 2つは form 用なので、 form 以外に使えるのは ERB::Util#url_encode しか残らない。 おや、よりによって唯一 module_function じゃないのが残ったか。
あまり正しくないことを確認してみる。
Unix では ? をファイル名に使えるので、 ~/public_html/question?mark というファイルを作れて、 とある HTTP サーバ(のとある設定)では、 これは http://host/~user/question%3Fmark という URI になる。
この URI を URI.escape の結果として生成できるかというと...
% ruby -ruri -e 'p URI.escape("http://host/~user/question%3Fmark")' "http://host/~user/question%253Fmark" % ruby -ruri -e 'p URI.escape("http://host/~user/question?mark")' "http://host/~user/question?mark"
やはり無理のようである。 なお、WEBrick::HTTPUtils.escape も同様である。
前者の結果は question%3Fmark というファイルへの参照になるし、 後者の結果は mark という query がついた question というファイルへの参照になる。 いずれにしても question?mark というファイルへの参照にはならない。
これを解決するには、%XX の % はそのままにしておくという手がある。 ただ、その挙動を後から変えるのが適切かどうかは微妙なところではある。
「原理的に、既にくっついちゃったひとつのuriを正しくencodeすることはできない。」
っていうのは規格からすると正しい考え方で、 それに反しているのがこの話のあまり正しくないところなわけです。
ところが、 URI ライブラリのマニュアルに、
require 'uri' $KCODE = 'EUC' p URI.escape('http://www.ruby-lang.org/ja/man-1.6/?cmd=view;name=Rubyリファレンスマニュアル')
とあり、その正しくないやりかたなのにもかかわらず、 結果的にいえば正しく動く例が出ていたりします。
というわけで、 どうもその正しい考え方というのは非直観的なのかもしれないという気がしています。
では直観的にするにはどうしたらいいかといえば、 ひとつの案は %XX の % は変えないというものですが、 もうひとつ思いついたのは Groovy の GString みたいなものを使うことですかね。 GString は、くっついちゃったように見えるけどじつはくっついてない、という文字列の記法なので、もしかしたら直観的かも知れない URI.escape みたいな用法を規格的にも正しく実装できるのかもしれません。
% google-count suri surl 285000 suri 94600 surl
花火
[latest]