[Rails][Tips] コントローラークラスにsendメソッドを定義するとInternal Server Error

最近、ちょっとした社内システムの構築に久々でRailsを使っているのですが、そこで遭遇したトラブルです。

Railsのコントローラークラスに send というメソッドを定義すると、Internal Server Errorが発生します。ログには次のように出力されます。

送信者 Knowledge-ex. Blog

Processing MaintController#index (for 127.0.0.1 at 2009-04-07 13:06:17) [GET]
Session ID: 84d33a01a55eaf629913bd764838be8b
Parameters: {"action"=>"index", "controller"=>"maint"}
/!\ FAILSAFE /!\  Tue Apr 07 13:06:17 +0900 2009
Status: 500 Internal Server Error
wrong number of arguments (1 for 0)

ブラウザではこんな表示です。

送信者 Knowledge-ex. Blog

Status: 500 Internal Server Error Content-Type: text/html
500 Internal Server Error

「send」というメソッドは、エラーログに「 C:/ruby/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/base.rb:524:in `send’」という記述があるように、ActionController::Baseの524行目で呼び出される内部的なメソッドの名称として使われているので、ユーザーのコントローラークラスでオーバーライドしてしまうと、本来呼ばれるべき内部のメソッドが参照されずユーザーが実装したメソッドが呼ばれてしまい、エラーになってしまうようです(直接の原因は「wrong number of arguments(1 for 0)」ということで、引数の数が不一致ということです)。

Javaの知識で例えれば、Servletの親クラスに定義されている内部メソッドをオーバーライドしてしまうようなものなので、こういった実装はやってはいけないというのは理解できますね。 ただ、sendというメソッドがActionController::Baseで定義されているかどうかは、少し詳しくソースを追いかけないと、よくわからないですね。

というわけで、ユーザーのコントローラクラスでsendというメソッドを定義したい場合は、ぐっとこらえて他の名称に変更して定義しましょう。