根据规格 http://www.ruby-doc.org/core-1.9.3/Hash.html#method-i-store,用作哈希键的字符串被复制并冻结。其他可变对象似乎没有这样特殊的考虑。例如,使用数组键,可以进行以下操作。
a = [0]
h = {a => :a}
h.keys.first[0] = 1
h # => {[1] => :a}
h[[1]] # => nil
h.rehash
h[[1]] # => :a
另一方面,使用字符串键无法完成类似的操作。
s = "a"
h = {s => :s}
h.keys.first.upcase! # => RuntimeError: can't modify frozen String
当涉及到哈希键时,为什么字符串的设计与其他可变对象不同?该规范是否有任何有用的用例?该规范还有哪些其他后果?
I actually have a use case where absence of such special specification about strings may be useful. That is, I read with the
yaml
gem a manually written YAML file that describes a hash. the keys may be strings, and I would like to allow case insensitivity in the original YAML file. When I read a file, I might get a hash like this:
h = {"foo" => :foo, "Bar" => :bar, "BAZ" => :baz}
我想将按键标准化为小写以获得以下结果:
h = {"foo" => :foo, "bar" => :bar, "baz" => :baz}
通过这样做:
h.keys.each(&:downcase!)
但由于上面解释的原因,这会返回一个错误。