at posts/single.html

検索でエラー

BitChannelにて、半角英数のみで検索しようとすると、以下のエラーがでてしまう。

BitChannel Error
private method `sub' called for ["BitChannel"]:Array (NoMethodError)
/home/matsuoka/public_html/bc/lib/bitchannel/locale/ja.rb:92:in `split_words'
/home/matsuoka/public_html/bc/lib/bitchannel/handler.rb:321:in `setup_query'
/home/matsuoka/public_html/bc/lib/bitchannel/handler.rb:315:in `search_regexps'
/home/matsuoka/public_html/bc/lib/bitchannel/handler.rb:189:in `handle_search'

loggerを使ってデバッグしたところ、 search_regexps が呼んでいる search_query が、 String でなく Array を返しているのが原因みたい。 この search_query は以下のように定義されている。

def search_query
  @locale.unify_encoding(get('q').to_s.strip)
end

「get('q').to_s.strip」は検索した語句(String型)を返しているので、怪しいのは @locale.unify_encoding になる。 これは lib/bitchannel/locale/ja.rb で定義されていて、文字コード変換ライブラリである Uconv や Iconv の有無で処理が切り替わるようになっている。 僕の環境では、 Iconv を使うロジックを通っていて Iconv.iconv を呼び出していた。

ここで、 Iconv.iconv が Array (Stringの配列)を返しているのが、エラーの原因になっているみたい。 これを以下のように書き換えたところ、エラーは出なくなった。

         def unify_encoding(text)
           dest = MIME_CHARSET_TO_ICONV[@encoding] or return unify_encoding_NKF(text)
-          Iconv.iconv(dest, 'UTF-8', text)
+          Iconv.iconv(dest, 'UTF-8', text).to_s
         rescue Iconv::Failure
           unify_encoding_NKF(text)
         end

ちなみに環境は ruby 1.8.1 。

追記(17日)

なぜ、全角で検索した場合はエラーにならなかったのだろう? 調べてみたら、textが全角の場合は「rescue Iconv::Failure」を通っている。 うむむ…。

あぁ、なるほど。 もともと text の文字コードが UTF-8 じゃなくて EUC-JP だから Iconv.iconv に失敗しているのか。 実害はなさそうだけど、意図した動作なのかは不明だなぁ。 検索語句が UTF-8 で送られてきた場合は Uconv か Iconv を使い、 それ以外の場合は NKF を使うって理解でいいのかな?

関連する日記