URI#encode, decode するのに $KCODE は要らない気がする

Ruby のリファレンスマニュアルを見ていると URI#encode のところで $KCODE をいじっている処理を見掛ける。

URI - Rubyリファレンスマニュアル

require 'uri'
$KCODE = 'EUC'
p URI.escape('http://www.ruby-lang.org/ja/man-1.6/?cmd=view;name=Rubyリ ..
=> \"http://www.ruby-lang.org/ja/man-1.6/?cmd=view;name=Ruby%A5%E ..

これ、要るんだろうか?

Ruby 1.8.7@OSX 10.5.7 + MacPorts で試す。

$ irb
irb(main):001:0> $KCODE=''
=> ""
irb(main):002:0> require 'uri'
=> true
irb(main):003:0> URI.encode( '日本語' )
=> "%E6%97%A5%E6%9C%AC%E8%AA%9E"
irb(main):004:0> $KCODE='u'
=> "u"
irb(main):005:0> URI.encode( '日本語' )
=> "%E6%97%A5%E6%9C%AC%E8%AA%9E"
irb(main):006:0> $KCODE='e'
=> "e"
irb(main):007:0> URI.encode( '日本語' )
=> "%E6%97%A5%E6%9C%AC%E8%AA%9E"

以上、encode については $KCODE の値はなんら影響なし。例によってこれを書いている時点では Ruby 1.8.7 で試して結果をコピペしてるけど、実際には 1.8.5 でも 1.8.6 でも試している。

irb(main):008:0> URI.decode( '%E6%97%A5%E6%9C%AC%E8%AA%9E' )
=> "日�\234�語"
irb(main):009:0> $KCODE='u'
=> "u"
irb(main):010:0> URI.decode( '%E6%97%A5%E6%9C%AC%E8%AA%9E' )
=> "日本語"
irb(main):011:0> $KCODE='e'
=> "e"
irb(main):012:0> puts URI.decode( '%E6%97%A5%E6%9C%AC%E8%AA%9E' )
日本語
=> nil
irb(main):013:0> $KCODE=''
=> ""
irb(main):014:0> puts URI.decode( '%E6%97%A5%E6%9C%AC%E8%AA%9E' )
日本語
=> nil

decode についても途中文字化けして見えるのは terminal が UTF-8 で、utf-8 の文字列を euc-jp の設定で無理矢理出力しようとしているのか、確かに化けて見えるが戻ってきた値を puts したものでは化けない。

つまり、戻り値の日本語に対して何かの操作を加えようとするなら $KCODE の値は意味があるかもしれないが、encode, decode 自体には関係ないように見えるんだけど、違うのかな?

Ruby 1.9.0@Debian lenny の場合。

$ irb
irb(main):001:0> $KCODE = 'u'
(irb):1: warning: variable $KCODE is no longer effective; ignored
=> "u"
irb(main):002:0> require 'uri'
=> true
irb(main):003:0> URI.encode( '日本語' )
=> "%E6%97%A5%E6%9C%AC%E8%AA%9E"
irb(main):004:0> $KCODE = 'e'
(irb):4: warning: variable $KCODE is no longer effective; ignored
=> "e"
irb(main):005:0> URI.encode( '日本語' )
=> "%E6%97%A5%E6%9C%AC%E8%AA%9E"
irb(main):006:0> $KCODE = 'u'
(irb):6: warning: variable $KCODE is no longer effective; ignored
=> "u"
irb(main):007:0> URI.decode( '%E6%97%A5%E6%9C%AC%E8%AA%9E' )
=> "\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E"
irb(main):008:0> puts URI.decode( '%E6%97%A5%E6%9C%AC%E8%AA%9E' )
日本語
=> nil
irb(main):009:0> $KCODE = 'e'
(irb):9: warning: variable $KCODE is no longer effective; ignored
=> "e"
irb(main):010:0> puts URI.decode( '%E6%97%A5%E6%9C%AC%E8%AA%9E' )
日本語
=> nil
irb(main):011:0> URI.decode( '%E6%97%A5%E6%9C%AC%E8%AA%9E' ).encoding
=> #<Encoding:ASCII-8BIT>

やっといてなんだけど $KCODE の値は ignored って言われてるんだから意味がない。この場合は locale が UTF-8 だから UTF-8 で解釈されるような気がしたんだけど、中身は ASCII-8BIT だった。

まぁ言いたいことはそういうことじゃなくて、戻り値に対して操作を加える必要がないなら URI#encode, decode 自体には $KCODE は関係ないよね?ってことでした。

More