class Hash

via github.com/citizen428/shenanigans/blob/master/lib/shenanigans/hash/has_shape_pred.rb

Public Instance Methods

has_shape?(shape, return_field = false) click to toggle source

Checks if a hash has a certain structure.

h = { k1: 1, k2: "1" }
h.has_shape?(k1: Integer, k2: String)
#=> true
h.has_shape?(k1: Class, k2: String)
#=> false

It also works with compound data structures.

h = { k1: [], k2: { k3: Struct.new("Foo") } }
shape = { k1: Array, k2: { k3: Module } }
h.has_shape?(shape)
#=> true
# File lib/obvious/contract.rb, line 185
def has_shape?(shape, return_field = false)
  return_value = lambda { |r, f|
    if return_field
      return r, f
    else
      return r
    end
  }

  # I added an empty check
  if self.empty?
    return return_value.call shape.empty?, nil
  end

  self.each do |k, v|
    return return_value.call false, k if shape[k] == nil
  end

  shape.each do |k, v|
    # hash_value
    hv = self[k]
    return return_value.call false, k unless self.has_key? k

    next if hv === nil

    if Hash === hv
      return hv.has_shape?(v, return_field)
    else
      return return_value.call false, k unless v === hv
    end
  end

  return_value.call true, nil
end
nil_fields?(list) click to toggle source
# File lib/obvious/contract.rb, line 220
def nil_fields? list
  list.each do |field|
    return true, field unless self[field]
  end

  return false, nil
end