UECジャーナル

ユニケージエンジニアの作法その二 elseの使用は控える

ユニケージエンジニアはelseを使用しないようにスクリプトを組み上げる。elifは使用するが、elseは使用しない。たとえば、手続き型プログラミング言語の発想でいえば、次のシェルスクリプトはよく記述するやり方だ。

if   [ $tensu = 100  ]; then
	message="よくできました!"
elif [ $tensu = 0    ]; then
	message="がんばろう!"
else
	message="まじめにやりなさい!!"
fi

elseは「それ以外」という条件を示すことになるが、ここに到達するまでに、それまでのすべての分岐条件を把握する必要がある。これはユニケージ開発手法的にはあまり直感的なものとはいえない。シェルスクリプトをテンポよく読んでもらうには、次のような書き方をする。

message="まじめにやりなさい!!"
if   [ $tensu = 100  ]; then
	message="よくできました!"
elif [ $tensu = 0    ]; then
	message="がんばろう!"
fi

elseに記述していた処理はデフォルトとして条件文を開始する前に実行する。

elseはインデントを深める原因

ユニケージ開発手法的な作法からいくと、elseにはもうひとつ問題がある。elseを使うと安易にインデントが深くなる。たとえば、手続き型プログラミング言語の発想からいえば、次のような条件文を記述することは珍しいことではない。

if [ $x -eq 0 ]; then
	if [ $y -eq 0 ]; then
		message="none"
	else
		message="y_only"
	fi
else
	if [ $y -eq 0 ]; then
		message="x_only"
	else
		message="both"
	fi
fi

ユニケージ開発手法はもともとプログラミングの専門家ではない現場の担当者がプログラミングできるようにすることを目的にしている。プログラミングやプログラミング的な思考に慣れた方であれば、上記のシェルスクリプトには何の問題もないが、不慣れが方にとってはこの条件文を理解するのにだいぶ長い時間を費やしてしまう。その間に新橋の飲み屋が閉まってしまっては、本末転倒である。ユニケージ開発手法的な書き方をすると、次のようになる。

if   [ $x -eq 0  -a  $y -eq 0 ]; then
	message="none"
elif [ $x -eq 1  -a  $y -eq 0 ]; then
	message="x_only"
elif [ $x -eq 0  -a  $y -eq 1 ]; then
	message="y_only"
elif [ $x -eq 1  -a  $y -eq 1 ]; then
	message="both"
fi

実際に使われているシェルスクリプトを読む

それでは実際にあるユニケージエンジニアが開発したjuni3danというスクリプトを読みながら、どういった方法でelseを使用せずにコーディングされているのかを追ってみよう。

juni3danはWebページの生成時に使われているコマンドだ。リストボックスの1番目で都道府県名を確定させたら、2番目のリストボックスに市区町村の選択肢を与え、そこも確定させたら3番目に町名の選択肢を与えるといった処理に使われている。基本の動作は次のようなものだ。フィールド形式の住所データを次のように加工する処理を担当している。

$ cat address.txt
東京都 千代田区 外神田
東京都 千代田区 内神田
東京都 港区 新橋
東京都 港区 西新橋
東京都 港区 愛宕
愛知県 名古屋市中区 大須
愛知県 名古屋市中区 栄
愛知県 名古屋市中村区 太閤
大阪府 大阪市中央区 日本橋
大阪府 大阪市中央区 千日前
$ juni3dan address.txt
1 1 1 東京都 千代田区 外神田
1 1 2 東京都 千代田区 内神田
1 2 1 東京都 港区 新橋
1 2 2 東京都 港区 西新橋
1 2 3 東京都 港区 愛宕
2 1 1 愛知県 名古屋市中区 大須
2 1 2 愛知県 名古屋市中区 栄
2 2 1 愛知県 名古屋市中村区 太閤
3 1 1 大阪府 大阪市中央区 日本橋
3 1 2 大阪府 大阪市中央区 千日前
$ 

このコードは最初は次のように記述されていた。

awk 'BEGIN { a=0; b=1; c=1; mae1=""; mae2=""; }

     {
	if      (mae1 != $1) { a++; b=1; c=1; }
	else if (mae2 != $2) {      b++; c=1; }
	else                 {           c++; }

	print a, b, c, $0;

	mae1=$1;
	mae2=$2
     }'

その後、ユニケージ開発手法の作法に準拠するように次のように書き換えられた。

awk 'BEGIN { a=0; b=1; c=1; mae1=""; mae2=""; }

     {
	if (mae1 != $1)               { a++; b=1; c=1; }
	if (mae1 == $1 && mae2 != $2) {      b++; c=1; }
	if (mae1 == $1 && mae2 == $2) {           c++; }

	print a, b, c, $0;

	mae1=$1;
	mae2=$2
     }'

elseどころかelse ifすら使っていないが、とにかくelseを使わないようにしている。書き換えたコードの方が、どの条件でどの処理が実行されるのかがわかりやすく、最終的にこのコードの動作を理解するまでの時間が短くなる。

ユニケージユニバーサル・シェル・プログラミング研究所の登録商標。

usp Tukubaiユニバーサル・シェル・プログラミング研究所の登録商標。

※ 本ページで公開されているプログラムとそれに付随するデータの著作権およびライセンスは、特に断りがない限りOpen usp Tukubai本体と同じMITライセンスに準拠するものとする。

USP MAGAZINE Vol.3「第一回 ユニケージエンジニアの作法」より加筆修正後転載。

Last modified: 2014-01-13 00:00:00