def implements(iface, options = {}, &block)
      unless iface.instance_of?(Module)  && iface.kind_of?(Interface)
        fail(TypeError, 'Argument must be a Implements::Interface Module')
      end

      params = {}
      params[:name] = options.fetch(:as) if options.key?(:as)
      groups = []
      groups << :default unless block_given?
      groups << :auto if options.fetch(:auto, true)
      params[:groups] = groups

      iface.register_implementation(self, params, &block)

      include iface
    end
def implements(iface, options = {}, &block)
      unless iface.instance_of?(Module)  && iface.kind_of?(Interface)
        fail(TypeError, 'Argument must be a Implements::Interface Module')
      end

      params = {}
      params[:name] = options.fetch(:as) if options.key?(:as)
      groups = []
      groups << :default unless block_given?
      groups << :auto if options.fetch(:auto, true)
      params[:groups] = groups

      iface.register_implementation(self, params, &block)

      include iface
    end
@api public
 @param iface [Module(Implements::Interface)]
 @param options [Hash{Symbol => Object}] - ({}) optional options hash
 @option options [Boolean] :auto - (true) whether to include this
   implementation in the interface's default search
 @option options [String] :as - The canonical name for this
   implementation, must be unique across all implementations.
 @option options [#to_s, Array<#to_s>] :groups - one or more named tags
   for this implementation, used for matching in Interface#implementation.

 If given, the block will be usde to determine the compatibility of this
 interface with the arguments that would be passed to the implementation's
 #initialize method.
 @yieldparam (@see self#initialize)
 @yieldreturn [Boolean]

 @return [void]
 @raises [TypeError] unless iface is a Implements::Interface Module