Ruby 1.9.2 CSV でInternal Encodingを指定するとおかしくなる件

今日これで数時間潰してしまったのでメモ。

Ruby 1.9のCSVでShift-JISのファイルを読み込むときのバグです。

[ruby]
# encoding: UTF-8

require ‘csv’

CSV.foreach(‘test.csv’, row_sep: “n”, encoding: “SJIS:UTF-8”) do |row|
puts row.join(‘:’)
end

CSV.foreach(‘test.csv’, encoding: “SJIS:UTF-8”) do |row|
puts row.join(‘:’)
end
[/ruby]

ファイル”test.csv”は以下のもので、行末は”n”でエンコーディングはShiftJISで保存してあります。

[text]
今日は,2月末なのに,東京でも,大雪でした

[/text]
ruby 1.9.2-p290で実行すると

[text]
NaoAir:Desktop nao$ ruby test.rb
今日は:2月末なのに:東京でも:大雪でした
/Users/nao/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/csv.rb:2027:in =~': invalid byte sequence in UTF-8 (ArgumentError)
from /Users/nao/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/csv.rb:2027:in
init_separators’
from /Users/nao/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/csv.rb:1570:in initialize'
from /Users/nao/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/csv.rb:1335:in
new’
from /Users/nao/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/csv.rb:1335:in open'
from /Users/nao/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/csv.rb:1201:in
foreach’
from test.rb:19:in `’

[/text]

のようになります。最初の”row_sep”を指定したものはうまくいきますが、”row_sep”を指定していない方はエラーが出ます。

理由は”row_sep”で行末記号を指定してあげないと、CSVは自分で先読みをして行末記号を推定しようとしますが、この処理がエンコーディングによってはバグを起こすようです。

解決策は最初の例のように行末記号をしてあげる、そもそも自動推定をさせないこと。あるいはCSVにtranscodeさせるのをやめ、CSVから得られた個々の結果を個別に#encodeしてあげること(下例)。
[ruby]
CSV.foreach(‘test.csv’, encoding: “SJIS”) do |row|
puts row.map{|c| c.encode(‘UTF-8’)}.join(‘:’)
end
[/ruby]

あるいはRuby 1.9.3ではこのバグは修正されているようですので、1.9.3にアップグレードすれば問題なく処理されます。

生き物の本質的難しさ

私は生物とプログラミングが同じ課題を抱えていて、お互いに似たような進化をしてきたのではないかという仮説を持っていますが、関連する記事をウェブで見つけました。

“現代的プロトタイピングのすすめ~古くて新しい可視化手法”

この記事は100%ソフトウェアについて書いてあるものですが、その中で1987年のFrederic P.Brooks, Jr.による著書「銀の弾丸はない:ソフトウェア工学の本質と課題」が紹介されています。

面白いのはその中の図表です。「ソフトウェア」を「生き物」と置き換えてもほとんどそのまま通じるように思いますが、いかがでしょうか。

NewImage

「生物の本質って何だろう」っていう疑問はよく聞く話で、例えば自己複製できることであるとか、エネルギーの流れ(代謝)であるとか言っている人がいます。それぞれに着眼点は素晴らしいと思います。でも私にとってはどの見解もあまりおもしろみを感じません。「生物」という存在と、現代人が築き上げた「技術」をつなげるような考えではないからです。

現代の高度な機械技術ことが人類の「バビルの塔」であり、人間が神に一歩ずつ近づこうとしている中間点だと私は思っています。そして神が築き上げた最高傑作こそが「生き物」。科学の究極的な目標が神の設計図を読み解き、理解し、模倣することであるとするのならば、「生命の本質」に関する議論もまた、どうやったら人工的に生命が作れるかに結びつかなければならないと思います。

この視点に立つと、人類が既に築き上げた技術力の中で、生物に最も近いものは何かを考えたくなります。

もし「生物の本質」を「複雑性」だと考えるならば、それは間違いなくプログラミングだと思います。私がここに着眼しているのはそのためです。

なお生物とプログラミングを比べてみることについて、私はこのブログでも過去に紹介していますので、ご覧下さい。(オブジェクト指向プログラミングと生物システムの類似性(作成中)オブジェクト指向プログラミングと生物学