def []=(index, filter)
      raise TypeError, 'must provide a filter' unless filter.respond_to?(:call)

      synchronize do
        id = index_at(index)
        unless id && (0..@filters.size).cover?(id)
          raise ArgumentError, "Cannot insert at index #{index.inspect}"
        end

        @filters[id] = filter
      end
    end
def []=(index, filter)
      raise TypeError, 'must provide a filter' unless filter.respond_to?(:call)

      synchronize do
        id = index_at(index)
        unless id && (0..@filters.size).cover?(id)
          raise ArgumentError, "Cannot insert at index #{index.inspect}"
        end

        @filters[id] = filter
      end
    end
Set the new filter at the given `index`. You can specify any existing
 filter or an index one above the highest index.

 @param index [Integer, Class, String, Object] The existing filter which
   should be overwritten with `filter`. It can be described in different
   ways: When given an `Integer`, we expect it to be the index number; when
   given a `Class`, we try to find the first filter being of that type;
   when given a `String`, we try to find the first filter being of a type
   named like that; when given any other object, we assume it is a filter
   and search for that.
 @param filter [#call, nil] the filter to set at `index`
 @raise [ArgumentError] if no existing filter could be found at `index`
 @raise [TypeError] if the given filter is not callable
 @return [#call] the given `filter`