ruby-1.9とsqlite3メモ
rubyを1.9にバージョンアップしたらw3mで使っていた
ローカルCGIが動かなくなったのでメモ。
原因は文字列の文字コードの扱いが変わったことだった。
リテラル
まずはリテラルの例
exp.rb
#!/usr/bin/env ruby str="文字列リテラル"
$ ruby exp.rb exp.rb:2: invalid multibyte char (US-ASCII) exp.rb:2: invalid multibyte char (US-ASCII)
怒られる
encodingを指定する。
#!/usr/bin/env ruby # -*- encoding: utf-8 -*- str="文字列リテラル" p str p str.encoding
$ ruby exp.rb "文字列リテラル" #<Encoding:UTF-8>
OK
外部からの文字列
外部としてsqlite3から文字列を入力する場合。
# UTF-8で文字列を格納 $ cat tmp.sql DROP TABLE IF EXISTS words; CREATE TABLE words ( id INTEGER PRIMARY KEY , word VARCHAR UNIQUE ); INSERT INTO words ( word ) SELECT "睦月" UNION ALL SELECT "如月" UNION ALL SELECT "弥生" ; # DB作成 $ sqlite3 tmp.db < tmp.sql
exp.rb
#!/usr/bin/env ruby # -*- encoding: utf-8 -*- require 'sqlite3' if ARGV.length<1 then exit end db=SQLite3::Database.new(ARGV[0]) db.execute("SELECT word FROM words") do |row| p row p row.map{|col| col.encoding} p row.map{|col| col.force_encoding 'utf-8'} end
実行
$ ruby exp.rb tmp.db ["\xE7\x9D\xA6\xE6\x9C\x88"] [#<Encoding:ASCII-8BIT>] ["睦月"] ["\xE5\xA6\x82\xE6\x9C\x88"] [#<Encoding:ASCII-8BIT>] ["如月"] ["\xE5\xBC\xA5\xE7\x94\x9F"] [#<Encoding:ASCII-8BIT>] ["弥生"]
リテラルでは無いので
# -*- encoding: utf-8 -*-
は効かない。
外部からの文字列はASCII-8BITになるので
encoding_forceforce_encodingでエンコード情報を与えてやるということらしい。
File.openやCGI経由での入力なんかも気をつける必要がある様子。
確かsqliteはutf-8を使う約束になっていたのでutf-8決めうちで
いいかもしれない。