Ruby のラムダ (およびブロックとプロシージャ) はクロージャーです。これは、ラムダが定義されているのと同じスコープで使用可能なローカル変数が、ラムダ内でアクセスできることを意味します。例えば:
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 (メソッドに渡されるパラメーター) はラムダによって「閉じられ」、ラムダが呼び出されるたびにその値が参照用に保持されます。
したがって、あなたの例では、ラムダは単に変数を「キャプチャ」し、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)