ruby-on-rails Ruby Hash中tap / delete和except的区别

brccelvz  于 2023-05-13  发布在  Ruby
关注(0)|答案(1)|浏览(192)

我正面临一个非常奇怪的行为。这是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)中,第一种语法的规范成功了,后两种语法失败了。我不知道确切地说明哪个测试是否重要,我只是在寻找一个解释。
有什么能解释为什么会这样吗?
先谢谢你了。

3qpi33ja

3qpi33ja1#

摘要

选项1使用Object#tapObject#tap
将self提供给块,然后返回self。此方法的主要目的是“接入”方法链,以便对链内的中间结果执行操作。
这不会创建一个“副本”,所以通过使用Hash#delete,您可以在适当的位置修改source
选项2和选项3确实会创建副本。
这意味着如果在测试中#1工作,而#2和#3不工作,那么可以合理地假设您正在测试source而不是result

TL;DR

让我们评估以下语句:* “带回不带:key密钥的source副本。"*
为简洁起见,我们将使用source = {key: 10}
示例和说明:

  • 示例1:result = source.tap { |s| s.delete(:key) }
    • “带回一个没有:key密钥的source副本。"* - FALSE。这将返回不带:key键的source
result = source.tap { |s| s.delete(:key) }
#= > {} 
result === source 
#=> true
source
# {}
  • 示例2:result = source.except(:key)
    • “Brings back a copy of the source without the :key key."* - TRUE(在Rails > 3.0和Ruby > 2.7中)
result = source.except(:key)
#=> {} 
result === source 
#=> false
source
# {key: 10}
  • 示例3:xlm 17 nlx
    • “带回source的副本,但不带:key密钥。"* - TRUE
result = source.dup.tap { |s| s.delete(:key) }
#=> {} 
result === source 
#=> false
source
# {key: 10}

相关问题