今日のはまったさん

Ruby1.8.6とRails1.1.6で、MySQL4.1系の構成でエラー。DB接続の途中でこけてるみたい。

ArgumentError (wrong number of arguments (1 for 0)):
/vendor/rails/activerecord/lib/active_record/vendor/mysql.rb:551:in `initialize'
/vendor/rails/activerecord/lib/active_record/vendor/mysql.rb:551:in `new'
/vendor/rails/activerecord/lib/active_record/vendor/mysql.rb:551:in `scramble41'
/vendor/rails/activerecord/lib/active_record/vendor/mysql.rb:141:in `real_connect'
/vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb:330:in `connect'
/vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb:87:in `initialize'
/vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb:36:in `new'
/vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb:36:in `mysql_connection'
/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb:251:in `send'
/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb:251:in `connection_without_query_cache='
/vendor/rails/activerecord/lib/active_record/query_cache.rb:54:in `connection='
/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb:220:in `retrieve_connection'
/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb:78:in `connection'

activerecord/lib/active_record/vendor/mysql.rbの551行目を確認。

  def scramble41(password, message)
    return 0x00.chr if password.nil? or password.empty?
    buf = [0x14]
    s1 = Digest::SHA1.new(password).digest         #551行目
    s2 = Digest::SHA1.new(s1).digest
    x = Digest::SHA1.new(message + s2).digest                                                                                                                                                                                                                                  
    (0..s1.length - 1).each {|i| buf.push(s1[i] ^ x[i])}
    buf.pack("C*")
  end   

Digest::SHA1のnewでエラー。
Rails1.2.3のactive_record/vendor/mysql.rbと比べてみました。

  def scramble41(password, message)
    return 0x00.chr if password.nil? or password.empty? 
    buf = [0x14] 
    s1 = Digest::SHA1.digest(password)    
    s2 = Digest::SHA1.digest(s1)   
    x = Digest::SHA1.digest(message + s2) 
    (0..s1.length - 1).each {|i| buf.push(s1[i] ^ x[i])}   
    buf.pack("C*")  
  end           

Digest::SHA1.new(password).digestじゃなくDigest::SHA1.digest(password)てな書き方になってますね。1.2.3の書き方に3行入れ替えたら無事動きました。
Rails Trac見てみました。http://dev.rubyonrails.org/changeset/6328

Ruby 1.8.6 compatibility: the bundled mysql.rb had used deprecated Digest::SHA1.new(...).digest instead of Digest::SHA1.digest(...)

おお、Ruby1.8.6でdeprecated。ということは、Railsを1.2.3にあげるか、Rubyを1.8.5に下げるか、直接手を入れて入れ替えるか。Rails1.2.3は諸事情によりわざわざ1.1.6を使ってるので却下。ruby1.8.5に下げるのも何となく却下。ということで、3行手を入れることにしました。
ローカルの開発環境では発生しなくて、本番環境にアップしたら発生したんですよね、これ。開発環境と本番環境の違いはMySQLのバージョン。141行目で4.1系の処理でscramble41を呼んでいて、そこでこけたと。開発環境はMySQL5.0系だったからなあ。やっぱり開発と本番は合わせておかないとねという話でした。反省。