Ruby中的匿名函数对象中的局部变量范围

时间:2013-03-09 05:42:29

标签: ruby

大卫。 A.布莱克在他的书中说:

  

“块可以作为匿名函数对象的主体,并且这些对象在创建时保留范围内的局部变量 - 即使函数对象被其他局部范围所占用。”

有人可以帮助我了解一些例子的含义吗?

1 个答案:

答案 0 :(得分:2)

当你创建一个匿名函数(lambdaProc)时,你给它一个块,这是函数的主体,如下所示:

-> { this_is_the_function_body }
Proc.new { this_is_the_function_body }

一个块保留在创建块的范围内存在的所有局部变量:

def my_lambda
  text = 'foo bar baz'
  -> { "text is: #{text}" }
end

l = my_lambda
text       #=> #<NameError: undefined local variable or method `text' for main:Object>
l.inspect  #=> "#<Proc:0x007f9863865a80@(pry):3 (lambda)>"
l.call     #=> "foo bar baz"

如上所述,即使lambda对象驻留在text不存在的作用域中,本地变量text仍然可用。如果调用范围中存在具有相同名称的局部变量,则甚至是这样:

text = 'something else'
l.call  #=> "foo bar baz"

这称为 closure 。无论您在何处调用该函数,您仍然可以访问创建它的范围。

这不仅适用于局部变量,而是整个范围,我们可以在这里看到:

class C
  def f; -> { g }; end
  def g; 'foo'; end
end

C.new.f.call  #=> "foo"