class Hash
  # Return a new hash filtered to exclude any key-value pairs whose keys appear
  # in +keys+.
  def discard *keys
    dup.discard!(*keys)
  end

  # Filter this hash in-place so any key-value pairs whose keys appear in
  # +keys+ are removed.
  def discard! *keys
    keys.each {|k| delete k }
    self
  end

  # Return a new hash filtered to contain only the key-value pairs whose keys
  # appear in +keys+.
  def slice *keys
    dup.slice!(*keys)
  end

  # Filter this hash in-place so it contains only the key-value pairs whose
  # keys appear in +keys+.
  def slice! *keys
    keys.inject({}) {|acc,key|
      acc[key] = self.delete(key) if self.has_key?(key)
      acc
    }
  end

  # Reverse-merge +other+ into this hash in-place; that is, merge all
  # key-value pairs in +other+ whose keys are not already present in self.
  def defaults! other
    Babushka::LogHelpers.deprecated! '2017-09-01', instead: '#merge! the other way around'
    replace other.merge(self)
  end

  # Return a new hash consisting of +other+ reverse-merged into this hash;
  # that is, equal to +other.merge(self)+.
  def defaults other
    Babushka::LogHelpers.deprecated! '2017-09-01', instead: '#merge the other way around'
    dup.defaults! other
  end

  # Return a new hash with the same keys as this hash, but with values
  # generated by yielding each key-value pair to +block+.
  def map_values &block
    keys.inject({}) {|acc,k|
      acc[k] = yield(k, self[k])
      acc
    }
  end

  # Return a new hash filtered to contain just the key-value pairs for which
  # the block returns true. That is, like Hash#select, but returning a hash
  # instead of an array of tuples.
  def selekt &block
    Babushka::LogHelpers.deprecated! '2017-09-01', instead: '#select'
    hsh = {}
    each_pair {|k,v|
      hsh[k] = v if yield(k,v)
    }
    hsh
  end
end
