どうにも、Railsのrespond_toメソッドがなんでこんな記述で動くのか良く判らなかったので、じっくり調べてみた。
def index @books = Book.all respond_to do |format| format.html # index.html.erb format.json { render json: @books } end end
lib\ruby\gems\1.9.1\gems\actionpack-3.1.0\lib\action_controller\metal\mime_responds.rb(42): def respond_to(*mimes) lib\ruby\gems\1.9.1\gems\actionpack-3.1.0\lib\action_controller\metal\mime_responds.rb(191): def respond_to(*mimes, &block)
include ActionController::ImplicitRender included do class_attribute :responder, :mimes_for_respond_to self.responder = ActionController::Responder clear_respond_to end module ClassMethods def respond_to(*mimes) options = mimes.extract_options! only_actions = Array(options.delete(:only)) except_actions = Array(options.delete(:except)) new = mimes_for_respond_to.dup mimes.each do |mime| mime = mime.to_sym new[mime] = {} new[mime][:only] = only_actions unless only_actions.empty? new[mime][:except] = except_actions unless except_actions.empty? end self.mimes_for_respond_to = new.freeze end def clear_respond_to self.mimes_for_respond_to = ActiveSupport::OrderedHash.new.freeze end end def respond_to(*mimes, &block) raise ArgumentError, "respond_to takes either types or a block, never both" if mimes.any? && block_given? if response = retrieve_response_from_mimes(mimes, &block) response.call(nil) end end def retrieve_response_from_mimes(mimes=nil, &block) #:nodoc: mimes ||= collect_mimes_from_class_level collector = Collector.new(mimes) { |options| default_render(options || {}) } block.call(collector) if block_given? if format = request.negotiate_mime(collector.order) self.content_type ||= format.to_s lookup_context.freeze_formats([format.to_sym]) collector.response_for(format) else head :not_acceptable nil end end def collect_mimes_from_class_level #:nodoc: action = action_name.to_sym self.class.mimes_for_respond_to.keys.select do |mime| config = self.class.mimes_for_respond_to[mime] if config[:except] !action.in?(config[:except]) elsif config[:only] action.in?(config[:only]) else true end end end
def foo(p1,p2,&block) block.call(p1,p2) end
foo("p1","p2") do |p1,p2| p p1 p p2 end
"p1" "p2"
foo("p1","p2") do |p1,p2| p p2 p p1 p "dummy" end
"p2" "p1" "dummy"
mimes ||= collect_mimes_from_class_level