The reason your #{item} W/COUPON entry is modifying your item entry is you've handed both of them the same info object. That is, after the two key assignments, your hash looks like this:
{
item => info,
"#{item} W/COUPON" => info
}
Looking at it this way, it's clear that modifying one value modifies the other, and in fact modifies the original info variable - they're all the same object. A simple way to make your hash_with_coupons values independent is to call dup on info as you do the assignment:
hash_with_coupons[item] = info.dup
hash_with_coupons["#{item} W/COUPON"] = info.dup
# Make modifications
Then each of your hash keys gets a copy of info. dup does what's called a shallow copy, making a new Hash object with the same values as the old one. This will work as long as your info hash values are simple, like Fixnums, and not references to more hashes, arrays, etc. that you want to modify. Otherwise, you'll need a deep copy or you'll run into the same problem you're having now, just one level deeper.
Since you're new, I'd recommend taking a different approach to better see which values are ending up in hash_with_coupons. Instead of assigning info and then modifying things inside your hash, assign brand new hashes with the data you want:
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
}
This guarantees that the values of hash_with_coupons are distinct objects, so you won't accidentally modify both when you change one. It also makes it very clear which values end up where, so you can easily see if you start sharing references again.