Ruby 为什么将字符串铲入散列会导致这种结果?

Ruby 为什么将字符串铲入散列会导致这种结果?,ruby,Ruby,我正在研究Ruby Koans,以便更好地掌握Ruby和TDD。我在关于_hashes.rb的代码中找到了第93行,这让我很困惑它是如何被推到默认构造函数而不是散列值中的。出于好奇,我尝试用同样的东西和字符串作为构造函数的参数,它产生了类似的结果 现在我的问题是,无论我使用什么键,为什么都会检索到相同的对象,以及如何在方法中的哈希中的特定键处将新对象铲入数组test\u default\u value\u是相同的对象? def test_default_value_is_the_same_obj

我正在研究Ruby Koans,以便更好地掌握Ruby和TDD。我在
关于_hashes.rb的代码中找到了第93行,这让我很困惑它是如何被推到默认构造函数而不是散列值中的。出于好奇,我尝试用同样的东西和字符串作为构造函数的参数,它产生了类似的结果


现在我的问题是,无论我使用什么键,为什么都会检索到相同的对象,以及如何在方法中的哈希中的特定键处将新对象铲入数组
test\u default\u value\u是相同的对象

def test_default_value_is_the_same_object
    hash = Hash.new([])

    hash[:one] << "uno"
    hash[:two] << "dos"

    assert_equal ["uno", "dos"], hash[:one] #why not ["uno"]?
    assert_equal ["uno", "dos"], hash[:two] #why not ["dos"]?
    assert_equal ["uno", "dos"], hash[:three] #why not []?

    assert_equal true, hash[:one].object_id == hash[:two].object_id
  end

def test_default_value_with_block
    hash = Hash.new {|hash, key| hash[key] = [] }

    hash[:one] << "uno"
    hash[:two] << "dos"

    assert_equal ["uno"], hash[:one]
    assert_equal ["dos"], hash[:two]
    assert_equal [], hash[:three]
end
def test_default_value_是同一对象
hash=hash.new([])

hash[:one]您已经创建了一个新的
hash
,当密钥不存在时,使用
数组作为累加器

hash = Hash.new([]) 
hash[:one] << "uno" 
hash[:one] == ["uno"] #=> true
要解决这个问题,可以使用第二次测试中提到的语法

hash = Hash.new {|h,k| h[k] = [] } 
这意味着对于每个新键,都要实例化一个新的
数组作为其值,而不是一次又一次地重复使用相同的
数组


这就是当
obj
是可变对象时,
Hash.new(obj)
语法的问题

有关原因的提示出现在测试名称中

test\u default\u value\u是\u同一个\u对象
显示,当您请求
散列[:一些尚未存在的\u值]
,默认情况下,您会返回指定的默认值——每次都是同一个对象。通过修改该对象,可以为每个不存在的键修改它。修改
散列[:one]
也会修改
散列[:two]


test\u default\u value\u with\u block
显示了使用块构造哈希的过程,该块将用于为每个键提供新值。当您这样做时,
hash[:one]
hash[:two]
的值是不同的。

“如何将新对象铲入数组hash[:one]”-嗯?就像你在上面做的那样
hash[:one]@SergioTulentsev我在问为什么hash[:one]上的数组与hash上的数组相同[:two]@marmeladze:
ruby koans
是一个元标记,请不要创建这样的标记,我们烧掉标记是有原因的,请注意,在执行
hash[:one]@SergioTulentsev时要注意一点,谢谢,我完全忘记了钥匙,甚至没有分配任何东西。我试过了,然后打印了值,结果就像我预期的那样。答案很清楚。
 a = []
 hash = {}
 hash.fetch(:one,a) << 'uno'
 hash.fetch(:two,a) << 'dos'
 hash.fetch(:three, a) 
 #=> ['uno','dos']
 hash
 #=> {}
hash = Hash.new {|h,k| h[k] = [] }