デビッド。A. ブラックは著書の中で次のように述べています。
「ブロックは無名関数オブジェクトの本体として機能し、それらのオブジェクトは、関数オブジェクトが他のローカル スコープで渡されたとしても、作成時にスコープ内にあるローカル変数を保持します。」
誰かがここで私がいくつかの例で何を意味するのかを理解するのを手伝ってくれますか?
デビッド。A. ブラックは著書の中で次のように述べています。
「ブロックは無名関数オブジェクトの本体として機能し、それらのオブジェクトは、関数オブジェクトが他のローカル スコープで渡されたとしても、作成時にスコープ内にあるローカル変数を保持します。」
誰かがここで私がいくつかの例で何を意味するのかを理解するのを手伝ってくれますか?
匿名関数(ラムダまたはProc)を作成するときは、次のように、関数の本体であるブロックを指定します。
-> { 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"
上記のように、ラムダオブジェクトが存在しないスコープに存在しtext
、スコープ内で呼び出された場合でも、ローカル変数は引き続き使用できます。text
これは、同じ名前のローカル変数が呼び出し元のスコープに存在する場合にも当てはまります。
text = 'something else'
l.call #=> "foo bar baz"
これはクロージャと呼ばれます。関数をどこで呼び出しても、関数が作成されたスコープにアクセスできます。
ただし、これはローカル変数だけに適用されるのではなく、ここに示すようにスコープ全体に適用されます。
class C
def f; -> { g }; end
def g; 'foo'; end
end
C.new.f.call #=> "foo"