問題のコ
categorized.keys.each do |c| PStore.new(cache_file(c)).transaction do |db| categorized.fetch(c) #=> key not found (KeyError) db['category'] = {} unless db.root?('category') db['category'].update(categorized[c]) end end
fetchをブロ
categorized.keys.each do |c| categorized.fetch(c) #=> O.K. PStore.new(cache_file(c)).transaction do |db| db['category'] = {} unless db.root?('category') db['category'].update(categorized[c]) end end
cache_file(c)の呼び出しが原因。その中でも includeしてある ERB::Utilの u()メソ
categorized.keys.each do |c| ::ERB::Util.u(c) categorized.fetch(c) #=> key not found (KeyError) PStore.new(cache_file(c)).transaction do |db| db['category'] = {} unless db.root?('category') db['category'].update(categorized[c]) end end
引数にした文字列のエンコ
categorized.keys.each do |c| enc1 = c.encoding; ::ERB::Util.u(c) enc2 = c.encoding categorized.fetch(c) { raise "#{enc1} #{enc2} #{::ERB.version}" } #=> UTF-8 ASCII-8BIT erb.rb [2.1.0 2009-01-11] (RuntimeError) PStore.new(cache_file(c)).transaction do |db| db['category'] = {} unless db.root?('category') db['category'].update(categorized[c]) end end
ERB::Util.url_encodeの定義を見ると、引数の文字列を dupした後にエンコ
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
そんなわけだから呼び出し側(category.rb)で
u( c.dup )
なんてや
u( ""+c )
あるいは
u( "#{c}" )
とや
これは、文字列の複製を遅らせた結果、期せずしておこ
バグのはずなんだけど、irbで再現しようと思
http://redmine.ruby-lang.org/issues/show/1929
(ここに、見るべき場所を見つけることもできなか
* 正しくは ruby-1.9.2dev(2009-02-03)