为什么这个Proc变量的对象是指变化?

时间:2013-08-31 16:15:29

标签: ruby closures scope

在这个Ruby 1.9.2代码中:

class ExampleClass
  def self.string_expander(str)
    -> do
      p "start of Proc.  str.object_id is #{str.object_id}"
      str *= 2
      p "end of Proc.    str.object_id is #{str.object_id}"
    end
  end
end

string = 'cat'                              # => "cat"
p "string.object_id is #{string.object_id}" # => "string.object_id is 70239371964380"
proc = ExampleClass.string_expander(string) # => #<Proc:0x007fc3c1a32050@(irb):3 (lambda)>
proc.call
                                            # "start of Proc.  str.object_id is 70239371964380"
                                            # "end of Proc.    str.object_id is 70239372015840"
                                            # => "end of Proc. str.object_id is 70239372015840"

第一次调用Proc时,str内的Proc开始引用原始对象,但在运行str *= 2操作后,引用另一个宾语。这是为什么?我预计原始字符串会被修改,而Proc会继续引用它。

1 个答案:

答案 0 :(得分:2)

分配时:

str = "abc"

str获取对象ID。如果你这样做了:

str[1] = 'd'

然后str的对象ID不会改变,因为您正在修改现有的字符串。

但是,如果您执行以下任何操作:

str = "123"
str = str * 2
str *= 2

您正在为str创建/分配新字符串,因此它的对象ID会发生变化。