返回包含在lambda中的方法引用

时间:2012-06-01 15:08:27

标签: ruby-on-rails ruby string reference lambda

请帮助我理解为什么以下有效。

class Dog
  def bark
    "woof"
  end
end

bark_string = Dog.new.bark
puts bark_string                   # "woof" - a string at this point
ref_to_bark = -> { bark_string }   # the string a moment ago is now the method again
ref_to_bark.call                   # "woof"

为什么在proc / lambda中包装对方法的引用会返回对原始方法的引用?这让我感到困惑。

3 个答案:

答案 0 :(得分:4)

没有。 ref_to_bark只返回bark_string,不调用bark方法。

答案 1 :(得分:3)

Ruby中的Lambdas(和块和过程)是closures;这意味着定义了与lambda相同范围内可用的局部变量,可以在 inside lambda中访问。例如:

foo = 42
l = lambda{ p foo }
l.call()
#=> 42

上述内容不应该比这段代码的工作更令人惊讶:

x = 17
[1,2,3].map do |n|
  n+x # Whoa, you can use _x_ here?!
end
#=> [18,19,20]

当你做这样的事情时,这会更令人惊讶:

def make_adder( x )
  ->(y){ x+y }
end
add10 = make_adder(10)
z = add10.call(32)     #=> 42

同样,局部变量 x (传递给方法的参数)由lambda“关闭”,每当调用lambda时,其值都会保留以供参考。

因此,在您的示例中,lambda只是“捕获”bark_string变量并稍后返回其值。永远不会再次调用您的方法。


请注意,闭包捕获变量本身,而不仅仅是变量引用的对象:

x = "hello"
y = x         # reference the same _object_
l = ->{ x }   # close over the _variable_ itself
x = "world"   # change the variable to point to a new object

p y,          #=> "hello"     (same object as the original)
  l[]         #=> "world"     (new object)

答案 2 :(得分:0)

使用 - >定义的lambda被称为lambda文字。有时被称为stabby lambda。以下内容也会返回相同的结果。

ref_to_bark = lambda { bark_string }

或者

ref_to_bark = lambda { "woof" }