merbのcontrollerのhook

merb-core/lib/merb-core/controller/abstract_controller.rb
_dispatchメソッドが肝

  • actionの実行前後にfilterが挟めるようになってる。filterはコントローラの暮す変数に追加している。
  • actionにdispatchする前後にもhookできるようになっている。(filterとの使い分けがいまいちわかってないので、これは後で)

  def _dispatch(action)
    self.action_name = action
    self._before_dispatch_callbacks.each { |cb| cb.call(self) }

    caught = catch(:halt) do
      start = Time.now
      result = _call_filters(_before_filters)
      @_benchmarks[:before_filters_time] = Time.now - start if _before_filters
      result
    end
  
    @body = case caught
    when :filter_chain_completed  then _call_action(action_name)
    when String                   then caught
    # return *something* if you throw halt with nothing
    when nil                      then "<html><body><h1>Filter Chain Halted!</h1></body></html>"
    when Symbol                   then __send__(caught)
    when Proc                     then self.instance_eval(&caught)
    else
      raise ArgumentError, "Threw :halt, #{caught}. Expected String, nil, Symbol, Proc."
    end
    start = Time.now
    _call_filters(_after_filters)
    @_benchmarks[:after_filters_time] = Time.now - start if _after_filters
    
    self._after_dispatch_callbacks.each { |cb| cb.call(self) }
    
    @body
  end