Vim script の lambda でクロージャ
Vim script の lambda ではローカル変数を変数をキャプチャできないので、function()
で変数を束縛することで実装してみました。
[実装イメージ]
function! Counter() let value = 0 function! Closure(local) let a:local.value += 1 return a:local.value endfunction return function("Closure", [l:]) endfunction let Count = Counter() echo Count() echo Count() echo Count() " => 1 " 2 " 3
[実装その1]
素直にそのまま lambda へと落としこんでみます。
let Counter = { \ -> [ \ execute("let value = 0"), \ function({ \ local -> [ \ execute("let local.value += 1"), \ local.value \ ][-1] \ }, [l:]) \ ][-1] \} let Count = Counter() echo Count() echo Count() echo Count() " => 1 " 2 " 3
複数の式を評価するためにリストを利用しています。
それ以外は execute()
を利用して変数の定義や代入を行っています。
[実装その2]
そもそもローカル変数の l:
は辞書なので辞書で代用してみる。
let Counter = { \ -> function({ \ local -> [ \ execute("let local.value += 1"), \ local.value \ ][-1] \ }, [{"value" : 0}]) \} let Count = Counter() echo Count() echo Count() echo Count() " => 1 " 2 " 3
ちょっとスッキリ。
[実装その3]
ここまで来たら辞書ではなくてもよいので、配列で代用。
let Counter = { \ -> function({ \ value -> [ \ execute("let value[0] += 1"), \ value[0] \ ][-1] \ }, [[0]]) \} let Count = Counter() echo Count() echo Count() echo Count() " => 1 " 2 " 3
ここまで来るともはや面影がないですね。
[使用した vim のバージョン]
- 7.4.2067