问题的一个较长的替代措辞是:“有哪些 Ruby 库或方法可以测试任意数据结构的形状(散列、数组、整数、 float 、字符串等)?”
首先,让我举一个简单的例子:
hash_1 = {
k1: 1.0,
k2: 42,
k3: {
k4: "100.00",
k5: "dollars"
}
}
接下来,我想验证它——我的意思是与形状/架构/模板进行比较,例如:
shape_a = {
k1: Float,
k2: Integer,
k3: Hash
}
或者,也许是更具体的形状:
shape_b = {
k1: Float,
k2: Integer,
k3: {
k4: String,
k5: String
}
}
一个可能的 API 可能如下所示:
require '_____________'
hash_1.schema = shape_a
hash_1.valid? # => true
hash_1.schema = shape_b
hash_1.valid? # => true
这些只是示例,我对其他方法持开放态度。
大约 3 年前,我写了 schema_hash去挠我自己的痒。我打算更新它,但首先我想了解替代方案和更好的方法。
这个问题的动机来自一个 Mongo 用例,但这个问题不一定是特定于 Mongo 的。
就像我在顶部提到的那样,我希望看到或构建验证任意数据结构的能力:散列、数组、原语等,在任何嵌套组合中。
“您不需要 Mongo 的模式,那您为什么要关心呢?”
- 正如我上面提到的,我不是唯一考虑 Mongo 用例
- 但即使在 Mongo 的上下文中,即使您不想要求数据结构采用某种形状,根据形状测试数据结构或模式并据此采取行动。
“为什么不直接编写自定义验证?”
当我处理之前的项目时,这正是我的起点。为嵌套的哈希重复编写验证一定很痛苦。我开始思考如何让它变得更容易,并想出了一个类似于我上面分享的语法。
外面有什么?我应该尝试什么?
综上所述,我很好奇其他人在做什么。有没有“黄金之路”?我正在尝试不同的方法,包括嵌入文档和 validates_associated with Mongoid例如......但是当哈希嵌套超过一个级别或这么深时,这些方法似乎有点矫枉过正。
我四处寻找 Validation on Ruby Toolbox用于验证(双关语),但没有找到我要找的东西。当我在那里时,我建议了一个名为“验证”的新类别。
很可能我要问的问题不太适合“验证”主题领域,而更适合其他主题领域,例如“数据结构”和“遍历”。如果是这样,请指出正确的方向。
最佳答案
编辑: 重新阅读您的问题,我的回答似乎过于简单。我会把它留给你,我是否应该删除它,请通过评论告诉我。
一个非常简单的方法是这样的:
class Hash
def has_shape?(shape)
all? { |k, v| shape[k] === v }
end
end
像这样使用:
hash_1.has_shape?(shape_a) #=> true
shape_b = { k1: Float, k2: Integer, k3: Integer }
hash_1.has_shape?(shape_b) #=> false
这似乎已经很好地处理了您描述的第一个版本。将它分解到库中并不难,因此它不会猴子修补 Hash
。向 has_shape?
方法添加递归将处理更复杂的情况。
更新:这是一个带递归的版本:
class Hash
def has_shape?(shape)
all? do |k, v|
Hash === v ? v.has_shape?(shape[k]) : shape[k] === v
end
end
end
关于ruby - 验证 Ruby 哈希的形状?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11106805/