是否有解决方案绕过“无法在迭代期间将新密钥添加到哈希(RuntimeError)”?

Posted

技术标签:

【中文标题】是否有解决方案绕过“无法在迭代期间将新密钥添加到哈希(RuntimeError)”?【英文标题】:Is there a solution to bypass 'can't add a new key into hash during iteration (RuntimeError)'? 【发布时间】:2014-10-01 14:44:01 【问题描述】:

我对预期的 RuntimeError 有一个大问题:"can't add a new key into hash during iteration"

在我的例子中,我有一个 YAML 文件:test.yaml - 我已经在其中添加了一些键。

test.yaml
key1:
key2:
key3:

我在一个变量中获取文件的内容:

file_hash = YAML.load_file("testm.yaml")

然后我需要遍历这个哈希并向它们添加其他键:

file_hash.each do |key|
   file_hash[key] = 'key_1'
   file_hash[key] = 'key_2'
end
File.open('test.yaml', 'w')  |f| YAML.dump(file_hash, f) 

主要问题是我无法在循环中写入哈希。当您有权控制循环块时,我不明白为什么会出现这种情况。 还有其他方法可以完成我上面展示的内容吗?

注意:我使用的是 RUBY 1.9.3 p547

【问题讨论】:

【参考方案1】:

Ruby 从 1.9 开始使用 lazy 迭代,因此它们禁止向您迭代的 hash 添加新键。作为一种解决方案,您可以在执行 each 之前轻松复制 hash 或将其转换为 array

irb(main):001:0> a=1=>1; a.each |k,v| a[2] = 2
RuntimeError: can't add a new key into hash during iteration

irb(main):002:0> a=1=>1; a.clone.each |k,v| a[2] = 2; a
=> 1=>1, 2=>2

irb(main):003:0> a=1=>1; a.to_a.each |k,v| a[2] = 2; a
=> 1=>1, 2=>2

【讨论】:

这个问题出现在我的一个项目中,其中包括 Ruby 1.8 到 1.9 的升级,这个解决方案对我有用。 这对我有用。我想知道为什么我的 2.2.2 脚本有效,而它在以前的版本中无效。谢谢。作为参考,请使用 a.to_a.each 让您轻松【参考方案2】:

您正在修改您正在迭代的哈希值。你做不到。

尝试另一种方法:

keys = [1,2,3,4]
file_hash = YAML.load_file("testm.yaml")
keys.each |key| file_hash[key] = 'key1' 
# => 1 => 'key1', 2 => 'key1', 3 => 'key1', 4 => 'key1'

【讨论】:

非常感谢。这很有帮助,但现在我面临另一个问题。对于插入的每个新键,我需要添加字符串值。问题是 yaml 将新键创建为字符串。有没有办法告诉 yaml 不要把键写成字符串?【参考方案3】:

我在

遇到了同样的错误
<%= stylesheet_link_tag 'application', 'data-turbolinks-track' => 'reload', media: 'all' %>

所以我重写了我的代码:

<% begin %>
  <%= stylesheet_link_tag 'application', 'data-turbolinks-track' => 'reload', media: 'all' %>
  <%= javascript_include_tag 'application', 'data-turbolinks-track' => 'reload' %>
<% rescue %>
  <script>
    window.location.replace "#user_session_url()"
  </script>
<% end %>

我不知道是什么导致了这个问题,但这个解决方法对我有用。我用

测试了它
ab -n 100 -c 10 -w http://localhost:3000/es

我没有收到任何错误消息

【讨论】:

【参考方案4】:

以前的答案对我没有帮助,所以我建议对我有帮助

a=1=>1; a = a.clone; a[2] = 2; a

【讨论】:

以上是关于是否有解决方案绕过“无法在迭代期间将新密钥添加到哈希(RuntimeError)”?的主要内容,如果未能解决你的问题,请参考以下文章

在 UICollectionView 中滚动时绕过 UIScrollViewDelegate

绕过 FreeMarker 缓存?

PHP常见绕过(更新ing)

一个网站图标引发的血案!绕过同源策略,判断你是否登录了某网站

如何使用SQLMap绕过WAF

(总结)绕过CDN查找真实IP