COBOLデザインパターン(Exit)
前回は、判断の部分をセクションに書き出して、メインのルーチンを簡単にしました。
http://d.hatena.ne.jp/Iwamoto/20080722/1216738870
なんというかくさいものにはフタ的な方法でしたが、今回のパターンは、道草食わずに処理を戻すというお利巧さんのパターンです。チェックロジックなどでは、よく使います。
前回の最後のソースでは、IF文のネストが深く、一見して何をしているのかよくわかりません。
* Switch2.cob : 複雑な条件判断はスイッチを用いて判定と処理を分割する IDENTIFICATION DIVISION. PROGRAM-ID. SWITCH2. ENVIRONMENT DIVISION. DATA DIVISION. WORKING-STORAGE SECTION. 01 IN-REC. 05 HH PIC 99. 05 FILLER PIC X(01). 05 MM PIC 99. 01 SW-AMPM PIC 9. 01 CNS-AMPM. 05 GOZEN PIC 9 VALUE 1. 05 SHOGO PIC 9 VALUE 2. 05 GOGO PIC 9 VALUE 3. 05 OWARI PIC 9 VALUE 4. PROCEDURE DIVISION. LOOP. DISPLAY '時間をHH:MM 形式で入力してね' ACCEPT IN-REC. MOVE 0 TO SW-AMPM. PERFORM S001-AMPM. EVALUATE SW-AMPM WHEN GOZEN DISPLAY '午前です。' WHEN SHOGO DISPLAY '正午です。' WHEN GOGO DISPLAY '午後です。' WHEN OWARI DISPLAY '終わりにします。' STOP RUN WHEN OTHER DISPLAY '時刻ではありません。' END-EVALUATE. GO TO LOOP. STOP RUN. *********************************************************************** S001-AMPM SECTION. IF HH < 12 THEN MOVE GOZEN TO SW-AMPM ELSE IF HH = 12 AND MM = 0 THEN MOVE SHOGO TO SW-AMPM ELSE IF HH = 99 AND MM = 99 THEN MOVE OWARI TO SW-AMPM ELSE MOVE GOGO TO SW-AMPM END-IF END-IF END-IF. EXIT.
ELSE IFが使えたならこんなことにはならないのですが・・・
まあ、それはそれとしてレベルをそろえましょう。
S001-AMPM SECTION. IF HH = 99 AND MM = 99 THEN MOVE OWARI TO SW-AMPM GO TO S001-AMPM-EX END-IF. IF HH < 12 THEN MOVE GOZEN TO SW-AMPM GO TO S001-AMPM-EX END-IF. IF HH = 12 AND MM = 0 THEN MOVE SHOGO TO SW-AMPM GO TO S001-AMPM-EX END-IF. MOVE GOGO TO SW-AMPM. S001-AMPM-EX. EXIT.
用事がすんだら、とっととセクションから出て行ってます。
このときにGO TOを使うので、嫌がる人がいるのですが、セクションの目的がはっきりしているのであれば問題が起こることはまずありません。理由は、GO TOがあることで、処理が明確になるからです。
(ほかの言語では、BREAKやRETURNなどが存在します。うらやまい。)
逆に、処理内容が明確でない場合にGO TOを使うのは悲劇の元です・・・
このパターンのメリットは、スイッチをつける優先順がはっきりすること。
さらに、ロジックの追加に強くなることです。
ちょっとやってみます。
たとえば、現在、分に60以上の数値を入力可能で、時間も24以上が入力可能です。
これを禁止するエラー判定ロジックを追加して見ます。
S001-AMPM SECTION. IF HH = 99 AND MM = 99 THEN MOVE OWARI TO SW-AMPM GO TO S001-AMPM-EX END-IF. IF HH > 23 OR MM > 59 THEN MOVE ERR TO SW-AMPM GO TO S001-AMPM-EX END-IF. IF HH < 12 THEN MOVE GOZEN TO SW-AMPM GO TO S001-AMPM-EX END-IF. IF HH < 12 THEN MOVE GOZEN TO SW-AMPM GO TO S001-AMPM-EX END-IF. IF HH = 12 AND MM = 0 THEN MOVE SHOGO TO SW-AMPM GO TO S001-AMPM-EX END-IF. MOVE GOGO TO SW-AMPM. S001-AMPM-EX. EXIT.
こんな感じ、ネストさせたIF文では、下位の階層を一段ずつずらすことになるので、「みなかったことにする。」コーダーさんもいらっしゃいますし、インデントを無視して追加するコーダーさんもいます。最悪な話ですけど・・・
とにかくこの方法は、蛇腹のようになったIF文のネストをすっきりさせる方法です。