为什么在Proc中分配的变量不会持续重复调用Proc?

时间:2013-09-04 14:25:57

标签: ruby block scope

Ruby 1.9.2代码:

def append_string_to_text(string_to_append)
  string_to_alter = 'starting_bit'
  p "OUTSIDE BLOCK: string_to_alter.object_id is #{string_to_alter.object_id}"
  Proc.new do
    p "****** START OF BLOCK: string_to_alter.object_id is #{string_to_alter.object_id}"
    p "defined?(new_string_created_in_block) is #{defined?(new_string_created_in_block) == true}"
    unless defined?(new_string_created_in_block)
      p "new_string_created_in_block is undefined. lets define it."
      new_string_created_in_block = 'test'
    end
    p "new_string_created_in_block.object_id is #{new_string_created_in_block.object_id}"
    string_to_alter = string_to_alter + string_to_append
    p "END OF BLOCK: string_to_alter.object_id is #{string_to_alter.object_id}"
    string_to_alter
  end
end

proc = append_string_to_text('_text_at_the_end')
p proc.call
p proc.call

输出:

"OUTSIDE BLOCK: string_to_alter.object_id is 70283335840820"
"****** START OF BLOCK: string_to_alter.object_id is 70283335840820"
"defined?(new_string_created_in_block) is false"
"new_string_created_in_block is undefined. lets define it."
"new_string_created_in_block.object_id is 70283335840520"
"END OF BLOCK: string_to_alter.object_id is 70283335840440"
"starting_bit_text_at_the_end"
"****** START OF BLOCK: string_to_alter.object_id is 70283335840440"
"defined?(new_string_created_in_block) is false"
"new_string_created_in_block is undefined. lets define it."
"new_string_created_in_block.object_id is 70283335840180"
"END OF BLOCK: string_to_alter.object_id is 70283335840100"
"starting_bit_text_at_the_end_text_at_the_end"

第一次运行块时,string_to_alter变量最初指向在append_string_to_text方法开始时创建的对象,因为该块是一个闭包。该块创建一个新变量new_string_created_in_block,然后创建一个新的块局部变量string_to_alter,它会遮蔽外部变量string_to_alter

第二次运行块时,string_to_alter变量最初指向第一次运行块时创建的对象。

为什么在第二次运行期间,new_string_created_in_block未定义?它是在第一次运行期间分配的,并且string_to_alter变量的分配从第一次运行开始持续存在,那么为什么new_string_created_in_block也不会持续存在?

1 个答案:

答案 0 :(得分:0)

string_to_alter被持久化,因为它位于Proc块之外且是闭包的一部分。 Proc块本身在每次调用时都会被实例化,因此块中定义的任何变量都不会持久存在。