在某些情况下,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]
我同意在迭代时修改哈希值不是很好。但是我看不到修改哈希和工作键方法之间的关系。
为什么会这样?
答案 0 :(得分:7)
有趣的问题。这还不是答案,但是发表评论的时间太长了,它可以帮助其他人回答问题。
我创建了一个具有非常简单规范的GitHub repository:
ComboBox
感谢Travis,很容易看出哪些Ruby版本存在此错误:
我刚刚花了一个小时使用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分钟发现了此提交。