Validating the shape of Ruby hashes?

Edit: Rereading your question my answer seems a bit too simplistic. I'll leave it up to your wether I should delete it or not, just let me know through a comment.

A very simple approach would be this:

class Hash
  def has_shape?(shape)
    all? { |k, v| shape[k] === v }
  end
end

Use like this:

hash_1.has_shape?(shape_a) #=> true
shape_b = { k1: Float, k2: Integer, k3: Integer }
hash_1.has_shape?(shape_b) #=> false

This already seems to be taking care of your first described version quite well. It wouldn't be hard to factor this out into a lib so it doesn't monkey-patch Hash. Adding recursion to the has_shape? method will take care of your more elaborate case.

Update: Here's a version with recursion:

class Hash
  def has_shape?(shape)
    all? do |k, v|
      Hash === v ? v.has_shape?(shape[k]) : shape[k] === v
    end
  end
end

This might be what you're looking for:

https://github.com/JamesBrooks/hash_validator

Tags:

Ruby

Mongodb