URI.encodeだっけCGI.escapeだっけ、そういえばuってaliasなかったけとなったので
ソース見てみました。
結論
こちらで議論されているように、CGI.escapeとERB::Util.uでは挙動が異なります。
ruby -r cgi -r erb -e 'puts CGI.escape("a b"), ERB::Util.u("a b")'
$ ruby -r cgi -r erb -e 'puts CGI.escape("a b"), ERB::Util.u("a b")' a+b a%20b
基本は、ERB::Util.uでいいのかな。(Railsのviewで使うならuでok)
CGI.escapeの方が早いらしいのでこの差を意識しない場合のみCGI.escapeでしょうか。
ソース抜粋
URI.encode
使っちゃダメです。
obsoleteでした。
#1.9.2/lib/ruby/1.9.1/uri/common.rb
module Escape def escape(*arg) warn "#{caller(1)[0]}: warning: URI.escape is obsolete" if $VERBOSE DEFAULT_PARSER.escape(*arg) end alias encode escape end extend Escape
関係ないけど、ソースのインデントにtabとspace併用してて気持ち悪い。
るりまサーチで調べると
singleton method URI.encode
このメソッドは obsolete です。 代わりに ERB::Util.url_encode, CGI.escape, URI.encode_www_form_component, WEBrick::HTTPUtils.escape_form, WEBrick::HTTPUtils.escape などの使用を検討してください。 詳細は [ruby-core:29293] からのスレッドを参照してください。
なんかいろいろあるのね。
ERB::Util.url_encode
#1.9.2/lib/ruby/1.9.1/erb.rb
class ERB module Util def url_encode(s) s.to_s.dup.force_encoding("ASCII-8BIT").gsub(/[^a-zA-Z0-9_\-.]/n) { sprintf("%%%02X", $&.unpack("C")[0]) } end alias u url_encode module_function :u module_function :url_encode end end
CGI.escape
#1.9.2/lib/ruby/1.9.1/cgi/util.rb
class CGI def CGI::escape(string) string.gsub(/([^ a-zA-Z0-9_.-]+)/) do '%' + $1.unpack('H2' * $1.bytesize).join('%').upcase end.tr(' ', '+') end end
正規表現での空白の扱いが異なります。
最後で空白を+に置換してますね。
あと、unpackの仕方が違うようですが、いまいちよくわかりません。
C:unsigned char (8bit 符号なし整数)
H2:16進文字列
おまけ WEBrick::HTTPUtils.escape_form
#1.9.2/lib/ruby/1.9.1/ebrick/httputils.rb
module WEBrick module HTTPUtils reserved = ';/?:@&=+$,' control = (0x0..0x1f).collect{|c| c.chr }.join + "\x7f" space = " " delims = '<>#%"' unwise = '{}|\\^[]`' nonascii = (0x80..0xff).collect{|c| c.chr }.join def _make_regex(str) /([#{Regexp.escape(str)}])/n end def _escape(str, regex) str.gsub(regex){ "%%%02X" % $1.ord } end UNESCAPED = _make_regex(control+space+delims+unwise+nonascii) UNESCAPED_FORM = _make_regex(reserved+control+delims+unwise+nonascii) def escape(str) _escape(str, UNESCAPED) end def escape_form(str) ret = _escape(str, UNESCAPED_FORM) ret.gsub!(/ /, "+") ret end end end
関係ないけど
CGI.escapeってなんでencodeじゃないんだろう。
html_escapeと混同すると思うんやけど。