Repository: rails/rails
File: actionpack/lib/abstract_controller/callbacks.rb (Ruby)

Code before:
    extend ActiveSupport::Concern

    # Uses ActiveSupport::Callbacks as the base functionality. For
    # more details on the whole callback system, read the documentation
    # for ActiveSupport::Callbacks.
    include ActiveSupport::Callbacks

    included do
      define_callbacks :process_action,
                       terminator: ->(controller, result_lambda) { result_lambda.call; controller.performed? },
                       skip_after_callbacks_if_terminated: true
    end

    class ActionFilter # :nodoc:
      def initialize(actions)
        @actions = Array(actions).map(&:to_s).to_set
      end

      def match?(controller)
        @actions.include?(controller.action_name)
      end

      alias after  match?
      alias before match?
      alias around match?
    end

    module ClassMethods
      # If +:only+ or +:except+ are used, convert the options into the
      # +:if+ and +:unless+ options of ActiveSupport::Callbacks.
      #
      # The basic idea is that <tt>:only => :index</tt> gets converted to
      # <tt>:if => proc {|c| c.action_name == "index" }</tt>.
      #
      # Note that <tt>:only</tt> has priority over <tt>:if</tt> in case they
      # are used together.
      #
      #   only: :index, if: -> { true } # the :if option will be ignored.
      #
      # Note that <tt>:if</tt> has priority over <tt>:except</tt> in case they
      # are used together.
      #
      #   except: :index, if: -> { true } # the :except option will be ignored.
      #
      # ==== Options
      # * <tt>only</tt>   - The callback should be run only for this action.
      # * <tt>except</tt>  - The callback should be run for all actions except this action.
      def _normalize_callback_options(options)
        _normalize_callback_option(options, :only, :if)
        _normalize_callback_option(options, :except, :unless)
      end

Review comment (suggestion):
This is equivalent, but way easier to read (and most likely faster):

```suggestion
            filter_names = @filters.length == 1 ? @filters.first.inspect : @filters.inspect
```

Code after:
    extend ActiveSupport::Concern

    # Uses ActiveSupport::Callbacks as the base functionality. For
    # more details on the whole callback system, read the documentation
    # for ActiveSupport::Callbacks.
    include ActiveSupport::Callbacks

    included do
      define_callbacks :process_action,
                       terminator: ->(controller, result_lambda) { result_lambda.call; controller.performed? },
                       skip_after_callbacks_if_terminated: true
      mattr_accessor :raise_on_missing_callback_actions, default: false
    end

    class ActionFilter # :nodoc:
      def initialize(filters, conditional_key, actions)
        @filters = filters.to_a
        @conditional_key = conditional_key
        @actions = Array(actions).map(&:to_s).to_set
      end

      def match?(controller)
        if controller.raise_on_missing_callback_actions
          missing_action = @actions.find { |action| !controller.available_action?(action) }
          if missing_action
            filter_names = @filters.length == 1 ? @filters.first.inspect : @filters.inspect
            message = "The #{missing_action} action could not be found for the #{filter_names} callback on #{controller.class.name}, but it is listed in its #{@conditional_key.inspect} option"
            raise ActionNotFound.new(message, controller, missing_action)
          end
        end

        @actions.include?(controller.action_name)
      end

      alias after  match?
      alias before match?
      alias around match?
    end

    module ClassMethods
      # If +:only+ or +:except+ are used, convert the options into the
      # +:if+ and +:unless+ options of ActiveSupport::Callbacks.
      #
      # The basic idea is that <tt>:only => :index</tt> gets converted to
      # <tt>:if => proc {|c| c.action_name == "index" }</tt>.
      #
      # Note that <tt>:only</tt> has priority over <tt>:if</tt> in case they
      # are used together.
      #
      #   only: :index, if: -> { true } # the :if option will be ignored.
      #