MSDOSバッチのややこしさ

MSDOSでバッチ作っていて変数の取り扱いがUNIXのシェルのように簡単に扱えないのにはびっくりした。普通に利用するには遅延環境変数の展開というなにやら難しい設定をしなければならない。
シェルの頭で以下のような定義を行い、変数の参照は!マークで囲むのである。
setlocal enabledelayedexpansion

set HENSUU="hohoho"

if !HENSUU! == "hohoho" (
set HENSUU="hehehe"
) else (
set HENSUU="kekeke"
)
echo !HENSUU!

endlocal

結果は期待どおり
$ hehehe


これを以下のように行うと期待どおりの結果にならない。
setlocal

set HENSUU="hohoho"

if %HENSUU% == "hohoho" (
set HENSUU="hehehe"
) else (
set HENSUU="kekeke"

)
echo %HENSUU%

endlocal

結果は期待どおり行かず
$ hohoho

これは環境変数の即時展開でこのようになるらしいのだが、なんともややこしい話である。プログラマは普通変数の値は最後にセットした値が有効になると思っているだろう。