Vim script の lambda で execute() を使うとローカル変数がキャプチャされない
さて、Vim script の lambda 内でローカル変数を使用すると自動的にキャプチャが行われます。
function! s:main() let value = 42 let F = { -> value + value } echo F() " => 84 let value = -4 echo F() " => -8 endfunction call s:main()
lambda 内で execute() を利用すると変数がキャプチャされない
例えば、次のように lambda 内で let
を使用したい場合は execute("")
を介してコマンドを呼び出します。
echo { -> [execute("let value = 42"), value + value][-1] }() " => 84
しかし、execute()
内でローカル変数を使用した場合、キャプチャは行われません。
function! s:main() let value = 0 let F = { -> execute("let value += 1") } " Error: E121: 未定義の変数です: value call F() endfunction call s:main()
これは execute()
内で『変数が使用されたかされてないか』とチェックしてないからぽいです。
例えば、次のようにして execute()
外でローカル変数を使用すれば問題なくキャプチャが行われます。
function! s:main() let value = 0 let F = { -> [execute("let value += 1"), value] } " OK call F() call F() call F() " ローカル変数は書き換えれてる echo value " => 3 endfunction call s:main()
意図しない動作ではあるけど、仕様ぽいなあ。