Hash#keys方法的输出错误

vov*_*van 10 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
Run Code Online (Sandbox Code Playgroud)

Ruby 2.3.8的输出:

{:b=>2, :c=>3}
[:b]
Run Code Online (Sandbox Code Playgroud)

Ruby 2.5.1输出:

{:b=>2, :c=>3}
[:b, :c]
Run Code Online (Sandbox Code Playgroud)

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

为什么会这样呢?

Eri*_*nil 7

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

哪些红宝石会受到影响?

我用一个非常简单的规范创建了一个GitHub 存储库

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
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明 感谢Travis,很容易看出哪些Ruby版本存在此错误:

  • Ruby 2.1
  • Ruby 2.2
  • Ruby 2.3

该错误何时出现?

错误何时修复?

我仅花了一个小时使用git bisectmake install来发现此提交中的错误已修复(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。

  • 包括/红宝石/ 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分钟发现了此提交。