def fetch_values(*keys, **options)
      values = values_at(*keys, **options)
      return values unless block_given?
      keys.zip(values).map do |key, value|
        if value == nil
          yield key
        else
          value
        end
      end
    end
def fetch_values(*keys, **options)
      values = values_at(*keys, **options)
      return values unless block_given?
      keys.zip(values).map do |key, value|
        if value == nil
          yield key
        else
          value
        end
      end
    end
Behaves identically to {#values_at} except that it accepts an optional
 block. When supplied, the block will be called successively with each
 supplied key that is not present in the store.  The return value of the
 block call will be used in place of nil in returned the array of values.

 @note Some adapters may implement this method atomically. The default
   implmentation uses {#values_at}.

 @overload fetch_values(*keys, **options)
   @param (see #values_at)
   @option options (see #values_at)
   @return (see #values_at)
 @overload fetch_values(*keys, **options)
   @param (see #values_at)
   @option options (see #values_at)
   @yieldparam key [Object] Each key that is not found in the store
   @yieldreturn [Object, nil] The value to substitute for the missing one
   @return [Array<Object, nil>] Array containing the values requested, or
     where keys are missing, the return values from the corresponding block
     calls
 @api public