挖法:
通过在每一步调用 dig 提取由 idx 对象序列指定的嵌套值,如果任何中间步骤为 nil,则返回 nil。
这意味着:
[1, {foo: :bar}].dig(1, :foo)
通过对对象和对象依次:bar
执行查找来返回。Array
Hash
第一次调用dig
是对一个Array
对象进行的,但下一次调用dig
是对Hash
从Array
.
使用dig
不违反得墨忒耳法则?
dig
几乎只是您在引入该方法之前执行的数组和哈希访问上的语法糖,因此它不会比您已经违反的或多或少违反得墨忒耳定律。考虑你的例子:
[1, {foo: :bar}].dig(1, :foo)
[1, {foo: :bar}][1][:foo]
你有相同的数据结构,你得到相同的值,但令人高兴的是,现在你不必检查nil
每一步。
得墨忒耳法则是一种设计启发式。如果您发现自己通过三个对象来完成某件事,那么执行此操作的代码必须了解所有这三个对象的相关信息。这表明您可能想要重构以减少模块所具有的依赖项的数量,但是您用来进行访问的方法(无论是[]
还是dig
)并不完全相关。
是的,可以说。但并不比通常的做法更重要,hash[:foo][:bar][:baz]
或者(更安全)hash[:foo] && hash[:foo][:bar] && hash[:foo][:bar][:baz]
。 dig
是这些的捷径。
我确实认为您走在正确的轨道上,即使用嵌套哈希来传递复杂数据类似于违反得墨忒耳法则,无论是否使用 dig,它都在做着得墨忒耳法则所反对的事情。从某种意义上说,您的代码需要了解哈希的结构,而不仅仅是调用具有清晰 API 的方法。然后可以说这dig
是对经常执行的 LoD 的一种违反 - 并使其更容易执行,纯粹主义者可能会说这是一个坏主意。
但在实际编程中,至少在 ruby 中,得墨忒耳法则更像是一个一般性的好主意,而不是一个要盲目遵循的实际法则。
人们也可以争辩说,在某些方面dig
避免了在没有它的情况下发生的 LoD 违规。从技术上讲,在使用时dig
您不再违反 LoD,因为您现在只是在您直接引用的对象上调用一种方法(一次dig
调用)。我不认为技术性太重要了,无论哪种方式,您实际上都在做同样的事情。