attr_internal_accessor
Railsのアクション内で、そういえばrequestやparamsとかってどうやってアクセスしてるのだろうと気になったので調べてみました。
とりあえずActionController::Baseを調べてるとassign_shortcuts(request, response)というメソッドを発見。
def assign_shortcuts(request, response) @_request, @_params, @_cookies = request, request.parameters, request.cookies @_response = response @_response.session = request.session @_session = @_response.session @template = @_response.template @assigns = @_response.template.assigns @_headers = @_response.headers end
インスタンス変数に色々いれてるけど、そんなものはみたことないのでとりあえず放置。んでattr_accessorかなと思ってみたら、attr_internal :requestとかってのを発見。調べてみました。
active_support/core_ext/module/attr_internal.rb
class Module # Declares an attribute reader backed by an internally-named instance variable. def attr_internal_reader(*attrs) attrs.each do |attr| module_eval "def #{attr}() #{attr_internal_ivar_name(attr)} end" end end # Declares an attribute writer backed by an internally-named instance variable. def attr_internal_writer(*attrs) attrs.each do |attr| module_eval "def #{attr}=(v) #{attr_internal_ivar_name(attr)} = v end" end end # Declares an attribute reader and writer backed by an internally-named instance # variable. def attr_internal_accessor(*attrs) attr_internal_reader(*attrs) attr_internal_writer(*attrs) end alias_method :attr_internal, :attr_internal_accessor private mattr_accessor :attr_internal_naming_format self.attr_internal_naming_format = '@_%s' def attr_internal_ivar_name(attr) attr_internal_naming_format % attr end end
やっぱりこれでした。文字列の%メソッドがわからなかったので調べてみました。
self % args
文字列のフォーマット。引数をフォーマット文字列(self)で書式化した文字列を返します。
args が配列であれば
sprintf(self, *args)
と同じです。それ以外の場合は、
sprintf(self, args)
と同じです。詳細は sprintfフォーマットを参照してください。
プログラミング言語 Ruby リファレンスマニュアル
sprintfだったのか。てことはやっぱり@_requestとかにアクセスしてるみたいですね。
@request変数にアクセスさせたくないけどアクセサは欲しいからこんなことやってる模様。activesupport-2.1.0/lib/active_support/deprecation.rbとかにちょろちょろ書いてます。黒魔術すぎる。。。