読者です 読者をやめる 読者になる 読者になる

単独eval読書会#02

vim

第二回は比較演算,制御コマンドです.

比較演算概要

vimでは真理値として数値が使われます.0が偽を意味し,それ以外は真を表します.

function! Func(arg)
  if a:arg
    echo 'true'
  else
    echo 'false'
  endif
endfunction


call Func(1) " true
call Func(2) " true
call Func(0) " false


call Func('hello') " false
call Func('2')     " true


call Func([1, 2]) " E745: Using a List as a Number
call Func(1.0)    " E805: Using a Float as a Number

リストや浮動小数点数は数値では無いためifで比較する際にエラーとなってしまいますが,文字列は型変換が行われます.
たとえば'hello'では0と解釈されるためfalseとなり,'2'では2と解釈され(0でないため)trueとなりました.

比較演算

基本的には他のスクリプト言語と同じです.気をつけるべき所はignorecaseオプションの有無でしょう.

setlocal noignorecase
echo 'a' ==  'A'
" 0
echo 'a' ==# 'A'
" 0
echo 'a' ==? 'A'
" 1


setlocal ignorecase
echo 'a' ==  'A'
" 1
echo 'a' ==# 'A'
" 0
echo 'a' ==? 'A'
" 1

この用に比較演算ではignorecaseがセットされるか否かで結果が変わってしまいます.
ignorecaseに関係なく文字の大文字小文字を考慮に入れる,あるいは入れない比較演算子が用意されています.
==#ではいつでも大文字小文字を区別する比較,==?では区別しない比較をします.

  'ignorecase'次第 大小文字考慮 大小文字無視
等しい == ==# ==?
等しくない != !=# !=?
より大きい > ># >?
より大きいか等しい >= >=# >=?
より小さい <# < ?
より小さいか等しい <= <=# <=?
正規表現マッチ =~ =~# =~?
正規表現非マッチ !~ !~# !~?
同一のインスタンス is is# is?
異なるインスタンス isnot isnot# isnot?

その他としては論理和論理積・三項間演算子があります.たとえば三項間演算子を用いれば概要に書いたFuncは

function! Func(arg)
  echo a:arg ? 'true' : 'false'
endfunction

のように書くことができます.

制御コマンド

if

if {expr}
elseif {expr}
else {expr}
endif

while

while {expr}
endwhile

for

for {var} in {list}
endfor

forはリストに対するイテレータの様な働きをします.なおwhile,forにはcontinueとbreakがあります.
Cで言うところのfor(i=0; i

echo range(5)
" [0, 1, 2, 3, 4] (0から数えて5個)

echo range(5, 10)
" [5, 6, 7, 8, 9, 10] (5から10まで)

echo range(0, 10, 2)
" [0, 2, 4, 6, 8, 10] (0から10までで2飛ばし)

for i in range(5)
  echo i
endfor

その他注意点としては,forでは型の異なる再定義でエラーとなる問題で,unletが必要となる場合があります.

for i in [1, 2, 'foo', ['bar', 3]]
  echo i
  unlet i " 変数を破棄しないとVariable type mismatchが起こる
endfor