Vim script の exists で autoload の関数は判定してはいけない

言われてみればそのとおりなんですが、ちょっとはまったので覚書。
Vim script では、ある変数や関数などが定義されているかを判定するために exists({expr}) という組み込み関数を使用します。
使い方は簡単で引数に定義されている変数名や関数名などを渡します

let has_xxx = exists("g:xxx")
let has_func_xxx = exists("*g:func_xxx")


さて、先日 webapi-vim のネームスペースが変更された時に最初は exists を使用して下記のように切り替える事を考えていました。

function! s:http_get(...)
    if exists("*webapi#http#get")
        return call("webapi#http#get", a:000)
    else
        return call("http#get", a:000)
    endif
endfunction

let body = s:http_get("http://hogehoge")


しかし、これではうまく動作しません。
なぜなら autoload で定義されている関数は実際にコールされるまでは存在しないので

exists("*webapi#http#get")

という式は webapi#http#get が1度でもコールされていない限り必ず 0 が返ってくるからです。


そんなわけで他にいい方法も思い浮かばなかったので try catch で切替を行っています。

function! s:http_get(...)
    try
        return call("webapi#http#get", a:000)
    catch /E117.*/
        echo "Please update webapi-vim"
        return call("http#get", a:000)
    endtry
endfunction

let body = s:http_get("http://hogehoge")