Ruby 为什么调整一个散列值也会改变另一个值?

Ruby 为什么调整一个散列值也会改变另一个值?,ruby,Ruby,我试图调整键“{item}W/优惠券”的哈希info的值,而不更改键项的info的值,这似乎是无意中发生的。所有这些都发生在嵌套哈希中 hash_with_coupons[item] = info hash_with_coupons[item][:count] = info[:count] - coupon_hash[:num] hash_with_coupons["#{item} W/COUPON"] = info hash_with_coupons["#{item} W/COUPON"][

我试图调整键
“{item}W/优惠券”
的哈希
info
的值,而不更改键
info
的值,这似乎是无意中发生的。所有这些都发生在嵌套哈希中

hash_with_coupons[item] = info
hash_with_coupons[item][:count] = info[:count] - coupon_hash[:num] 
hash_with_coupons["#{item} W/COUPON"] = info
hash_with_coupons["#{item} W/COUPON"][:price] = coupon_hash[:cost]
hash_with_coupons["#{item} W/COUPON"][:count] = 1
此代码运行后

  • 用优惠券[项目][:价格]==优惠券散列[:成本]
  • 用优惠券[项目][:计数]==1散列\u
但是它们应该分别是原价和优惠券散列。

你的
{item}W/优惠券
条目修改你的
条目
的原因是你把相同的
信息
对象交给了他们。也就是说,在两个键分配之后,哈希如下所示:

{
  item               => info,
  "#{item} W/COUPON" => info
}
从这个角度看,很明显修改一个值会修改另一个值,事实上修改原始的
info
变量-它们都是相同的对象。使您的
hash\u与\u优惠券
值独立的一种简单方法是,在执行作业时,在
info
上调用
dup

hash_with_coupons[item] = info.dup
hash_with_coupons["#{item} W/COUPON"] = info.dup
# Make modifications
然后,每个哈希键都会获得
info
的副本
dup
执行所谓的浅层复制,生成一个新的
Hash
对象,其值与旧对象相同。只要您的
info
散列值很简单,比如
Fixnum
s,并且不引用您想要修改的更多散列、数组等,这将起作用。否则,您将需要一个更高的级别,否则您将遇到与现在相同的问题,只是更深一层

由于您是新来的,我建议您采取不同的方法,以便更好地查看哪些值以优惠券的形式出现在
hash\u中。与其分配
info
,然后修改散列中的内容,不如使用所需的数据分配全新的散列:

hash_with_coupons[item] = {
  price: info[:price],
  count: info[:count] - coupon_hash[:num]
}
hash_with_coupons["#{item} W/COUPON"] = {
  price: info[:price] - coupon_hash[:cost],
  count: 1
}

这保证了
hash\u with\u优惠券
的值是不同的对象,因此在更改某个对象时不会意外地修改这两个对象。它还非常清楚哪些值在哪里结束,因此您可以很容易地看到是否再次开始共享引用。

您可以发布更多代码吗,可能会显示您正在使用嵌套哈希构建的数据结构?最好的方法是发布足够的代码,以便人们可以将其粘贴到IRB中并进行测试。如果您使用过于复杂的哈希结构,您可能希望采用更面向对象的方法,并使用类、方法、,我认为读者不会理解你的问题。(我不知道。)我建议您编辑以显示
优惠券散列
优惠券散列={…}
)并显示您想要生成的散列。这可能需要几分钟,因此我进一步建议您删除该问题,进行编辑,然后取消删除。您保留的时间越长,您就越有可能获得否决票和/或结束投票。在第一次分配后,
使用优惠券[项目]
信息对同一对象进行散列。因此,
hash\u与优惠券[item][:count]=…
相当于
info[:count]=…
。您可能需要分配
info
的(深层)副本。