【COBOL 読み3-12】ENDまとめ系 あたしたちきれいに別れましょ?


🧩今日の学び
ENDは単なる終了記号ではなく「構造の境界宣言」であり、支配領域を明示するための結界である
AT ENDELSEではなく「最後まで探索した結果」のみ発火する特殊条件である
・COBOLを読む力とは、インデントとENDを追い続けて構造のねじれを見抜く力である

係長) そろそろ…か。

なるお) なにがすか?

係) いや、なんでもない。

な) ??

係) 今日はENDをまとめていくぞ。地獄だ。いいな。

な) えー!またぁ!?

係) うるさい!いいからやるぞ!

な) ふわーい……

ENDは「終わり」じゃない、「ここまで」の宣言

係) まず、お前、これ読めるか?

IF A = 1
    PERFORM UNTIL B = 10
        IF C = 5
            DISPLAY "HIT"
        END-IF
    END-PERFORM
END-IF

な) うーんと… Aが1だったら、PERFORMに入って10までルーピング。

んで、Cが5だったら、HITと表示してEND-IF終了。END-PERFORM。外側END-IFって感じっすよね。

係) なんとなくだと事故の始まりになるぞ。

地獄その1:「このENDどこのやつ?」

な) 正直、END-IF ってどのIFのやつなの!?どこの子なの!?って感じっすね。

迷子の子に服を引っ張られて、大声で泣いちゃって、案件になって、通報されちゃうんすよね。

何もしてないのに逮捕される世の中なんすよね。

係) お前はこの世のリスクみたいなもんだからな。仕方ないだろ。

な) いやん。

係) COBOLはこれらが全部ある。

  • END-IF
  • END-PERFORM
  • END-SEARCH
  • END-EVALUATE

全部「明示終了符」だ。 つまり、必ず閉じろ。曖昧にするなよ。

なぜこんなにENDが多いかって言うとだ…昔のCOBOLはこうだった。

IF A = 1
    DISPLAY "OK".

ピリオドで終了。

だが問題が起きた。

な) 係長に愛人がいたとか?

係) なんでだよ!俺は一途なんだよ!

な) おー!純愛!

係) …って、い、いいから!

これだと、どこまでがIFの範囲かわからんだろ!

ネストが深くなると、ピリオド一つ打つだけで、その外側のIFまで全部強制終了してしまう。そして、事故る。

だから今は「範囲を明示しろ」になったんだ。

つまり、END-IF はただの終わりじゃない。構造の境界宣言なんだ。

な) 境界っすか? んー

教会で協会が境界決めるぅ!そして俺は後悔 いぇー!

みたいな感じですかね。

係) 何言ってんだお前?

いいか、「ここまでがIFの支配領域。ここから外!」 それを明確にするための結界だ。

ネスト地獄とインデントの命

地獄その2:ネスト地獄

IF A = 1
    IF B = 2
        IF C = 3
            DISPLAY "OK"
        END-IF
    END-IF
END-IF

な) これもうインデント命っすよね。

係) その通り。 COBOLはインデントが命、崩れたら死ぬ。

な) すぐ殺そうとするんだから… 悪い癖っすよ…

係) してねーだろ!

地獄その3:PERFORMと混ざる

PERFORM UNTIL EOF
    IF FLAG = "Y"
        PERFORM PROCESS-REC
    END-IF
END-PERFORM

な) これ、END-PERFORM 忘れたら?

係) ログが真っ赤になる。そして原因探しに30分だな。

な) なんすかその血の池地獄!?

あ、でも池ってなんかスケール感がしょぼい感じしますよねー。

血の銀河地獄ぐらいにバージョンアップしたほうがいいんじゃないすかね。

係) どういうことだよ… ま、お前だけが地獄なら、それでも良いんだが。

な) いやいやいやいや

係) まとめるとこうだ。

  1. ENDはただの終わりではない
  2. 構造の境界宣言
  3. インデントが命
  4. ピリオド地獄よりはマシ

つまり「読む力」とは、「ENDを追いかける力」と考えておけ。

COBOLは上から順番に読む言語だが、ENDを追えないと迷子になるからな。

な) 俺、迷子の子うさぎちゃんでいいっすよ…

係) 迷子アライグマとか、殺処分だろ。

な) 自分は、たぬきのくせに(ボソ

係) 聞こえてんだよ!

ループはELSEでは止まらない

な) あ、待ってくださいにー。

ふと思ったんですけど、今回ELSE無いじゃないすか。

ってことはルーピングって10まで絶対行くんすか? それとも見つかった時点でEND-PERFORMなんすか?

係) ふむ。

ELSEが無いことと、ループが止まるかどうかは関係ないんだ。

な) ほー。

係) いいか、止まる条件は2つだ。

  1. UNTIL の条件が真になる
  2. 中で EXIT PERFORM する

ELSEがあろうがなかろうが、これ以外では止まらない。

な) ほー?

係) まず、さっきの形を思い出せ。

PERFORM UNTIL B = 10
    IF C = 5
        DISPLAY "HIT"
    END-IF
END-PERFORM

ここでループを止めている条件はどこだ?

な) えーと…、UNTIL B = 10 っすよね。

係) そうだな。 PERFORM UNTIL は、「条件が真になったら終わる」という意味だ。

じゃあ途中で止まるかというと、止まらない。

C = 5が見つかっても、DISPLAYするだけで、ループ終了条件は変わらない。

な) え、じゃあ「HIT」と表示されたあとも普通に回り続けるんすか?

係) そうだ。10になるまで回る。

途中で止めたいなら、例えば

  • PERFORM UNTIL B = 10 OR C = 5 (条件を足す)
  • EXIT PERFORM (脱出する)

のどっちかが必要になる。

な) あー前世でやったやつですね…。

でも俺、室町時代あたりは麻呂麻呂言って蹴鞠してただけなんで。

係) お前が貴族レベルなわけ無いだろが!

な) ひど!

SEARCHのENDはELSEじゃない

係) 次は、SEARCHのEND地獄だ。

な) なんで、地獄つけたがるのこの人…

SEARCH ITEM-TABLE
    AT END
        DISPLAY "NOT FOUND"
    WHEN ITEM-ID(IDX) = TARGET-ID
        DISPLAY "FOUND"
END-SEARCH

な) これ普通じゃないすか?

係) 普通に見えるだろ?ここから崩れる。

地獄その1:AT ENDは「ELSE」じゃない

な) AT END って、IF文でいう ELSE みたいなもんじゃないんすか?

係) 違う。AT END「探索が最後まで行ったときだけ実行」だったろ。

  • WHEN → 条件ヒットで即終了
  • AT END → 全部探して見つからなかったら実行

な) そっか、ELSE(条件不一致なら毎回)と勘違いすると事故るわけですなぁ。

地獄その2:END-SEARCH忘れ

SEARCH ITEM-TABLE
    WHEN ITEM-ID(IDX) = TARGET-ID
        IF FLAG = "Y"
            PERFORM PROCESS-REC
        END-IF
END-IF       *> ← これがやらかし例

IFSEARCHが混ざると、END-IFEND-SEARCH が交錯する。

な) えーでも間違います?

係) 単純なコードなら間違わないかもしれないが、複雑なコードだとどのENDかを見間違う可能性が高くなっていくってことだ。

これやるとログ真っ赤になるぞ。お前はやるだろうが。

な) きぃぃ!

係) ちなみに閉じ忘れるとより地獄だ。

SEARCH ITEM-TABLE
    WHEN ITEM-ID(IDX) = TARGET-ID
        IF FLAG = "Y"
            PERFORM PROCESS-REC
END-SEARCH    *> ← IFを閉じてない!

な) IFを閉じてないってことすかね。

係) そうだ。これだとコンパイルエラーだな。

な) むー。

END-IF忘れちゃってた、てへ!」が通じないとは…

係) 通じるわけないだろ!

そもそも人間の気持ちは関係ない。COBOLは構造しか見てないんらな。

な) 人をみてー!心を感じてー!このアツいパッションを感じてー!

係) 本当に怖いのはこれだ。

な) あ、スルーすか⋯

IF A = "1"
    SEARCH ITEM-TABLE
        WHEN ...
            PERFORM PROC
    END-IF      *> !?
END-SEARCH      *> !?

な) IFとSEARCHを逆に閉じちゃった。でへへ!

係) 濁点つけるなよ!気持ち悪い。

な) 気持ち悪いって、あんた…

係) これだと、コンパイラによっては「どっちも閉じているからOK!」と通してしまうこともある。

だが、中身の構造はグチャグチャだ。Aが”1“じゃない時にSEARCHが動いたり、その逆が起きたりで、本番で死ぬぞ。

な)何回死ぬんすか…

地獄その3:SEARCHの中でIF

係) 例えばこうだ。

SEARCH ITEM-TABLE
    AT END
        DISPLAY "NOT FOUND"
    WHEN ITEM-ID(IDX) = TARGET-ID
        IF FLAG = "Y"
            DISPLAY "HIT"
        END-IF
END-SEARCH

な) これもうインデントしてないと見られたもんじゃないすね…。

係) SEARCHAT ENDがある分、さらにインデントが迷子になりやすいからな。

だからインデントは命となるんだ、

な) ほむー。

地獄その4:SEARCH ALLはさらに地獄

係) SEARCH ALL は二分探索だから前提条件があったってことは覚えてるだろ?

な) 天上界にあるクラウドに保存してますよ。人間の英知がぎゅうぎゅうにつまっているあれっす。

係) …つまり、お前の記憶にはないということだよな…

な) 必要なときはクラウドから引っ張り出しますからー!

係) 今がそのときだろが! ったく、これだ。

  • テーブルはソート済み
  • ASCENDING / DESCENDING KEY指定必須

これ忘れると、「見つかるはずのデータが見つからない」。しかもエラー出ないからな。

な) あー言ってましたね。

係) それは覚えてたか。

おむすび

な) しっかし、いろんな地獄があるもんすね。

血の宇宙の外側地獄とか怖すぎですよね。

係) なんでスケールアップさせてるんだよ…。

ま、お前みたいにふわふわやってると必ず地獄見るぞ。

な) 係長はそうやって地獄の鬼たちにやられて、係長の顔が鬼以上に変わっていったんですねー。納得です。

係) うるせーな!どこに納得する要素があるんだよ!

な) あ、前世からそのまんまだったってことっすよね…。すみません。

係) じゃかーしぃ!!

係長のワンポイント

ENDは処理を止める記号じゃない。
ここまでが支配領域だ、と宣言する境界線だ。
ELSEが無くてもループは止まらないし、AT ENDELSEでもない。
構造を勘違いすると、静かにねじれて本番で爆発する。
COBOLを読む力とは、ENDを追い続ける力だ。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする