BLOGTIMES
2010/10/16

Ruby/MySQL で Mysql::ProtocolError が出たときに確認すべきこと

  ruby 
このエントリーをはてなブックマークに追加

Ruby/MySQL を使って書かれたコードを Ruby 1.9 で動かそうとしたら、これまで見たことがないMysql::ProtocolErrorというエラーが出るようになってしまって参りました。

結論から述べると Ruby 1.9 では -K オプションをつけるのはやめましょうねという話。

試しに全く同じコードを Ruby 1.8 の環境に持って行ったところ、ちゃんと動作するので、じゃあ再現コードがどれだけシンプルにできるかと思ってどんどんコードを削っていったら、下記のようなごく簡単なコードでも再現することが分かりました。

test.rb

require 'rubygems' require 'mysql' conn = Mysql::connect('localhost','testuser','testpass','testdb') res = conn.query("select now()") res.each do |row| p row end

一瞬、Ruby/MySQL が Ruby 1.9 に対応していないのかと思いましたが、ウェブには 1.9 対応と書かれているし、同じようなエラーで悩んでいる人も見あたらないので、何か手がかりはないかとひたすら試行錯誤していたら、偶然コマンドラインオプションをつけ忘れたときにうまく動くことを発見。そういえば、Ruby 1.9 は -Kx オプションは非推奨になってたことを思い出しました。

C:\tmp>ruby test.rb ["2010-10-16 23:10:09"] C:\tmp>ruby -Ku test.rb C:/Ruby192/lib/ruby/gems/1.9.1/gems/ruby-mysql-2.9.3/lib/mysql/protocol.rb:629:in `read_eof_packet': packet is not EOF (Mysql::ProtocolError) from C:/Ruby192/lib/ruby/gems/1.9.1/gems/ruby-mysql-2.9.3/lib/mysql/protocol.rb:317:in `retr_fields' from C:/Ruby192/lib/ruby/gems/1.9.1/gems/ruby-mysql-2.9.3/lib/mysql.rb:321:in `query' from test.rb:5:in `<main>' C:\tmp>ruby -Ks test.rb C:/Ruby192/lib/ruby/gems/1.9.1/gems/ruby-mysql-2.9.3/lib/mysql/protocol.rb:629:in `read_eof_packet': packet is not EOF (Mysql::ProtocolError) from C:/Ruby192/lib/ruby/gems/1.9.1/gems/ruby-mysql-2.9.3/lib/mysql/protocol.rb:317:in `retr_fields' from C:/Ruby192/lib/ruby/gems/1.9.1/gems/ruby-mysql-2.9.3/lib/mysql.rb:321:in `query' from test.rb:5:in `<main>'

こんな感じで、 -K オプションを使わなければうまく動くようです。ちょっと詳しい理由は分からないのですが、 -K オプションはストリームの入出力にも影響を及ぼしてしまうということなのでしょうか。Ruby 1.9 でストリーム関係のエラーが出た場合には -K オプションを使っていないかどうかという事を確認するようにした方が良さそうです。

参考

Rubyist Magazine - Ruby M17N の設計と実装

コマンドラインオプション -K は Ruby 1.9 でも非推奨ながら健在です。Ruby 1.9 での -K は script encoding のデフォルト (-K が無ければ US-ASCII) と、Encoding.default_external に影響します。(Encoding.default_internal は nil のままになります)

なお、-K が script encoding に影響するのは、あくまで互換性確保のための処置で、1.8 のコードを修正なしに 1.9 でも動かしたい場合に利用するものです。1.8 でも 1.9 でも動くようにしたい場合や、1.9 用に新規に書く場合は magic comment を用いてください。

ちなみに改めて検索してみたら「Ruby/MySQL で ProtocolError が出るとき - Mi manca qualche giovedi`?」に同様の事例が報告されていました。


    トラックバックについて
    Trackback URL:
    お気軽にどうぞ。トラックバック前にポリシーをお読みください。[policy]
    このエントリへのTrackbackにはこのURLが必要です→https://blog.cles.jp/item/3853
    Trackbacks
    このエントリにトラックバックはありません
    Comments
    愛のあるツッコミをお気軽にどうぞ。[policy]
    古いエントリについてはコメント制御しているため、即時に反映されないことがあります。
    エラーメッセージでぐぐってきました (2012/12/13 13:41) <%HatenaAuth()%>

    同じ問題ではまりました。助かりました。
    ありがとうございます!

    Comments Form

    コメントは承認後の表示となります。
    OpenIDでログインすると、即時に公開されます。

    OpenID を使ってログインすることができます。

    Identity URL: Yahoo! JAPAN IDでログイン