Ruby 从'each'方法保留两个变量的值

Ruby 从'each'方法保留两个变量的值,ruby,Ruby,我有以下代码: session={"apple"=>["bp", "80APPM", "donald"]} @like_list = session @like_list.each do |key, value| value.each_with_index do |v, i| @like_list[key][i] = 2 end end session # => {"apple"=>[2, 2, 2]} @like_list # => {"apple

我有以下代码:

session={"apple"=>["bp", "80APPM", "donald"]}
@like_list = session
@like_list.each do |key, value|
  value.each_with_index do |v, i|
    @like_list[key][i] = 2
  end
end
session    # => {"apple"=>[2, 2, 2]}
@like_list # => {"apple"=>[2, 2, 2]}
分配给变量
会话
@like_list
的对象都已更改。是否有任何方法可以在不更改
会话
值的情况下执行上述代码


我试着使用
clone
dup
,但没有改变使用
Hash.deep\u dup

@like_list = session.deep_dup
对于方法

编辑:

此方法来自Rails附带的
activesupport
库。正如评论中所建议的,这种方法过去是有问题的,但是,它的表现更令人期待。我测试了上面的示例,它与
ActiveSupport4.2.3
一起工作

如果未使用Rails,则需要加载:


您需要复制原始散列,以防止两个变量引用同一对象

@like_list = session.map { |key, value| [key, value.clone] }.to_h
这项工作:

session={"apple"=>["bp", "80APPM", "donald"]}
@like_list = Marshal.load(Marshal.dump(session))
@like_list.each do |key, value|
  value.each_with_index do |v, i|
    @like_list[key][i] = 2
  end
end

它使用
Marshal.load(Marshal.dump(session))
解决方案来解决这个SO问题:

dup和clone是浅拷贝,请参阅:@sawa,对不起,是个打字错误。它应该是“@like_list”散列#deep_dup不适用于包含的数组。试试看。@MichaelGaskill您使用的是哪个ruby版本?我运行的是2.3.0,它可以运行Ruby 2.2.5、2.1.9和1.9.3,但它们都不能运行。它必须装在新的里面。这个bug已经存在很多年了……我正在使用Ruby 2.3和Rails 4。deep_dup方法对我很有效。两个变量值都保留。谢谢依我看,你回答了一个没有被问到的问题。如果没有一个规范说明
session[“apple”]
可以有多个嵌套级别,并且给定的值没有嵌套,那么我们应该假设没有嵌套,在这种情况下,加载
activesupport
(注意没有Rails标记)是过分的。演示如何处理嵌套是很好的,但只能作为旁白。此方法适用于单级哈希,但如果存在任何嵌套级别,则顶层以下的级别仍将被浅层复制。要使这项工作正常,您需要处理任意级别的嵌套。@Michael,问题没有指定多个嵌套级别,并且指定的
session
值只有一个,所以这个答案很好,我的评论只是想警告那些试图在一般情况下使用这种方法的人。问题和答案的使用寿命很长。
Marshal.load(Marshal.dump(session))。每个带有{u对象({})的{u对象({u})(k,v),h[k]=[2]*v.size}
@像{u列表=Marshal.load(Marshal.dump(session))。点击{h}h.each{k,v{h[k]=[2]*v.size}
,但正如我在其他评论中指出的那样,我认为这个问题不需要深究。
session={"apple"=>["bp", "80APPM", "donald"]}
@like_list = Marshal.load(Marshal.dump(session))
@like_list.each do |key, value|
  value.each_with_index do |v, i|
    @like_list[key][i] = 2
  end
end