我正面临一个非常奇怪的行为。这是Ruby 2.6.6,因此可以修改冻结散列。在本例中,source
被冻结。
这样做:
result = source.tap { |s| s.delete(:key) }
返回不带:key
密钥的source
副本。
从理论上讲,这也是:
result = source.except(:key)
还有这个
result = source.dup.tap { |s| s.delete(:key) }
根据我的理解,上述3种语法具有相同的结果。
然而,在测试(Ruby 2.6.6,Rails 6.0.6.1)中,第一种语法的规范成功了,后两种语法失败了。我不知道确切地说明哪个测试是否重要,我只是在寻找一个解释。
有什么能解释为什么会这样吗?
先谢谢你了。
1条答案
按热度按时间3qpi33ja1#
摘要
选项1使用
Object#tap
。Object#tap
:将self提供给块,然后返回self。此方法的主要目的是“接入”方法链,以便对链内的中间结果执行操作。
这不会创建一个“副本”,所以通过使用
Hash#delete
,您可以在适当的位置修改source
。选项2和选项3确实会创建副本。
这意味着如果在测试中#1工作,而#2和#3不工作,那么可以合理地假设您正在测试
source
而不是result
。TL;DR
让我们评估以下语句:* “带回不带
:key
密钥的source
副本。"*为简洁起见,我们将使用
source = {key: 10}
示例和说明:
result = source.tap { |s| s.delete(:key) }
:key
密钥的source
副本。"* - FALSE。这将返回不带:key
键的source
。result = source.except(:key)
source
without the:key
key."* - TRUE(在Rails > 3.0和Ruby > 2.7中)source
的副本,但不带:key
密钥。"* - TRUE