Hash#keys方法的输出错误

时间:2019-07-05 08:43:07

标签: ruby

在某些情况下,Hash#keys在2.4版之前的Ruby中无法正常工作

演示代码:

h = { a: 1, b: 2, c: 3 }
h.each do |k, v|
    h.delete(:a)
    p h
    p h.keys
    break
end

Ruby 2.3.8输出:

{:b=>2, :c=>3}
[:b]

Ruby 2.5.1输出:

{:b=>2, :c=>3}
[:b, :c]

我同意在迭代时修改哈希值不是很好。但是我看不到修改哈希和工作键方法之间的关系。

为什么会这样?

1 个答案:

答案 0 :(得分:7)

有趣的问题。这还不是答案,但是发表评论的时间太长了,它可以帮助其他人回答问题。

哪些红宝石受到影响?

我创建了一个具有非常简单规范的GitHub repository

ComboBox

enter image description here 感谢Travis,很容易看出哪些Ruby版本存在此错误:

  • Ruby 2.1
  • Ruby 2.2
  • Ruby 2.3

该错误何时出现?

该错误何时修复?

我刚刚花了一个小时使用describe Hash do it "should always know which keys are left" do h = { a: 1, b: 2, c: 3 } h.each do |k, v| h.delete :a expect(h.keys).to eq [:b, :c] end end end git bisect来发现此commit (75775157)中的错误已得到修复。

  

介绍弗拉基米尔·马卡罗夫(Vladimir Makarov)制作的桌子   

     

[功能#12142]有关改进的详细信息,请参见st.c的标题。

     

您可以在此处查看所有代码历史记录:     https://github.com/vnmakarov/ruby/tree/hash_tables_with_open_addressing

     

有关改进之处,请参见     https://bugs.ruby-lang.org/issues/12142和很多人在一起,   尤其是尤拉·索科洛夫(Yura Sokolov)。

     
      
  • st.c:改进st_table。

  •   
  • include / ruby​​ / st.h:同上。

  •   
  • internal.h,numerical.c,hash.c(rb_dbl_long_hash):提取一个   功能。

  •   
  • ext / -test- / st / foreach / foreach.c:赶上此更改。

  •   
     

git-svn-id:svn + ssh://ci.ruby-lang.org/ruby/trunk@56650   b2dd03c8-39d4-4d8f-98ff-823fe69b080e

@Vovan已确认,他在我这样做之前1分钟发现了此提交。