ユニケージエンジニアは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を使うと安易にインデントが深くなる。たとえば、手続き型プログラミング言語の発想からいえば、次のような条件文を記述することは珍しいことではない。
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「第一回 ユニケージエンジニアの作法」より加筆修正後転載。