参见英文答案 >
+= operator appears to modify frozen string2
我正在学习Ruby,而在使用Object#freeze方法和变量时,我发现有趣的行为.
我正在学习Ruby,而在使用Object#freeze方法和变量时,我发现有趣的行为.
在我冻结一个变量(Fixnum或Array)之后,我仍然可以修改它!这是奇怪的,因为就我而言,这不应该发生,应该引发TypeError.
这是我的代码:
test = 666 var = 90 #ok var += 5 puts "var.frozen? #{var.frozen?}" var.freeze puts "var.frozen? #{var.frozen?}" var = test puts "var = #{var}"
阵列也是如此:
test = [666] var = [90] #ok var += [5] puts "var.frozen? #{var.frozen?}" var.freeze puts "var.frozen? #{var.frozen?}" var = test puts "var = #{var}"
但是当我试图在冻结之后把东西推到阵列中时,就像预期的那样引起了一个恐怖:
test = [666] var = [90] #ok var += [5] puts "var.frozen? #{var.frozen?}" var.freeze puts "var.frozen? #{var.frozen?}" var << test puts "var = #{var}"
有人可以向我解释这个问题吗?好像很奇怪
编辑我使用的是Windows XP Ruby 1.9.3-p429
解决方法
您冻结对象而不是变量,即不能更新冻结对象,但可以将新对象分配给同一个变量.考虑这个:
a = [1,2,3] a.freeze a << 4 # RuntimeError: can't modify frozen Array # `b` and `a` references the same frozen object b = a b << 4 # RuntimeError: can't modify frozen Array # You can replace the object referenced by `a` with an unfrozen one a = [4,5,6] a << 7 # => [4,6,7]
除此之外:冻结Fixnums是非常无用的,因为它们是不可变的对象.