他の回答は、動作の違いはInteger
s が不変であり、Array
s が可変であるためであることを示しているようです。しかし、それは誤解を招くものです。違いは、Ruby の作成者が一方を不変にし、もう一方を可変にすることを決定したことではありません。違いは、プログラマーが一方を変更することを決定し、もう一方を変更しないことです。
問題はArray
s が変更可能かどうかではなく、変更できるかどうかです。
sを使用するだけで、上記の両方の動作を取得できますArray
。観察:
Array
突然変異を伴う1 つのデフォルト
hsh = Hash.new([])
hsh[:one] << 'one'
hsh[:two] << 'two'
hsh[:nonexistent]
# => ['one', 'two']
# Because we mutated the default value, nonexistent keys return the changed value
hsh
# => {}
# But we never mutated the hash itself, therefore it is still empty!
Array
突然変異のない1 つのデフォルト
hsh = Hash.new([])
hsh[:one] += ['one']
hsh[:two] += ['two']
# This is syntactic sugar for hsh[:two] = hsh[:two] + ['two']
hsh[:nonexistant]
# => []
# We didn't mutate the default value, it is still an empty array
hsh
# => { :one => ['one'], :two => ['two'] }
# This time, we *did* mutate the hash.
Array
突然変異で毎回違う、新しい
hsh = Hash.new { [] }
# This time, instead of a default *value*, we use a default *block*
hsh[:one] << 'one'
hsh[:two] << 'two'
hsh[:nonexistent]
# => []
# We *did* mutate the default value, but it was a fresh one every time.
hsh
# => {}
# But we never mutated the hash itself, therefore it is still empty!
hsh = Hash.new {|hsh, key| hsh[key] = [] }
# This time, instead of a default *value*, we use a default *block*
# And the block not only *returns* the default value, it also *assigns* it
hsh[:one] << 'one'
hsh[:two] << 'two'
hsh[:nonexistent]
# => []
# We *did* mutate the default value, but it was a fresh one every time.
hsh
# => { :one => ['one'], :two => ['two'], :nonexistent => [] }