根据规范,用作哈希键的字符串会被复制并冻结。其他可变对象似乎没有这样的特殊考虑。例如,对于数组键,可以执行以下操作。
另一方面,使用字符串键无法完成类似的操作。
为什么字符串在哈希键方面被设计成与其他可变对象不同?这个规范有哪些用例?这个规范还有哪些后果?
实际上,我有一个使用案例,其中缺乏关于字符串的特殊规范可能是有用的。也就是说,我使用
通过像这样做:
但是由于上述原因,这会返回一个错误。
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
为什么字符串在哈希键方面被设计成与其他可变对象不同?这个规范有哪些用例?这个规范还有哪些后果?
实际上,我有一个使用案例,其中缺乏关于字符串的特殊规范可能是有用的。也就是说,我使用
yaml
gem读取手动编写的描述哈希的YAML文件。键可以是字符串,并且我想在原始YAML文件中允许不区分大小写。当我读取一个文件时,我可能会得到像这样的哈希:h = {"foo" => :foo, "Bar" => :bar, "BAZ" => :baz}
我希望将键名统一转换为小写,得到以下结果:
h = {"foo" => :foo, "bar" => :bar, "baz" => :baz}
通过像这样做:
h.keys.each(&:downcase!)
但是由于上述原因,这会返回一个错误。
h.keys.each{|s| h.store(s.downcase, h.delete(s))}
。 - sawah.transform_keys!(&:downcase)
。 - Sundeep