🧩今日の学び
・SEARCHは「探す命令」ではなく、INDEXを進めながら条件を1件ずつ評価する構造
・ITEM-RECを探しているのではなく、IDXが指す位置を順に確認しているだけ
・魔法に見える命令ほど、中身はPERFORMという基本構造に立ち返ると理解できる
係長)えーとSEARCHやるぞ…
なるお)へ!?
いや、なんすか、いきなりぷしゅ〜って気が抜けたんすか?またあんなに興奮してたのに、やるやる詐欺すか?
係)うるさいな。結果やるんだから詐欺じゃないだろ。
な)遠回りが過ぎますよー。
東京から品川行くのに、群馬から名古屋に行って品川に戻ってくる感じじゃないすか!
係)どういうことだよ…こっちの方がお前を地獄に叩き落とせると思えば、ノッてくるってもんだろう。
な)叩き落すって…生き甲斐が無さすぎですから!
係)いいからいくぞ。お待ちかねのSEARCHなんだぞ。
な)別に待ってはないですけど…
係)お前がSEARCH、SEARCHうるさいんだろ!
な)係長が飛ばすからでしょー!
係)ま、いいからいくぞ。
な)むー。
係)なんで不満顔なんだよ!
SEARCHは「探す命令」ではない
係)SEARCHは「OCCURS配列を上から順に探す専用命令」だ。
な)なんだかいきなりですね…。
って、あれ、だったらPERFORMでいくないです?
係)まぁそうだな。実務では8割それでいい。
だが、SEARCHには「役割」があるんだ。
SEARCHが使える条件は3つだけだ。
OCCURSがあるINDEXED BYがあるSETでINDEXを初期化している
が必要だ。
な)三種の神器っすか…。牛丼・親子丼・キムチ牛丼ってところすかね。
係)それ二種だろ…。
01 ITEM-TABLE.
05 ITEM-REC OCCURS 5 TIMES
INDEXED BY IDX.
10 ITEM-ID PIC X(3).
10 ITEM-NAME PIC X(10).
01 TARGET-ID PIC X(3) VALUE "003".
SET IDX TO 1
SEARCH ITEM-REC
AT END
DISPLAY "見つかりません"
WHEN ITEM-ID(IDX) = TARGET-ID
DISPLAY "見つけた: " ITEM-NAME(IDX)
END-SEARCH
係)前に示したコードだ。読んでみろ。
な)ウィムッシュ。
え…と、まず…OCCURS 5 TIMESとか言っちゃってるから、ITEM-RECって箱を5個用意する。IDXはINDEXに定義しましたよーと。ITEM-IDは3文字にした。ITEM-NAMEは10文字にした。
TARGET-IDは3文字で003とした。
が上の二つの部分ですよね。
IDXを1にセットしてITEM-RECをSEARCH…だから探す??
あ、違うか。IDXはインデックスだから、IDXの1番目の箱を探すってことだとして?ITEM-RECを探す?なんで?
意味わかんないんですけど…
係)気にするな
SEARCHは「書いてあること」と「やってること」がズレて見える命令だからな。わからなくて当然ともいえる。
まずSEARCHの前にSET IDX TO 1を書いて、SEARCH自体は内部でこれをやってる。
SET IDX TO 1
PERFORM UNTIL IDX > 最大件数
IF ITEM-ID(IDX) = TARGET-ID
処理
EXIT PERFORM
END-IF
SET IDX UP BY 1
END-PERFORM
最初お前は、
IDXを1にセットしてITEM-RECをSEARCH…だから探す??
と言っていたが、そこが一番の勘違いポイントとなる。
INDEXという前提:SEARCHは矢印を動かしている
ITEM-RECを探してるんじゃない。ITEM-RECの中身を、IDXを使って順番に調べているんだ。
な)はい?
係)上の定義部を「日本語」に直すとだ、
01 ITEM-TABLE.
05 ITEM-REC OCCURS 5 TIMES
INDEXED BY IDX.
10 ITEM-ID PIC X(3).
10 ITEM-NAME PIC X(10).
ITEM-RECは5個並んでいる
- それぞれに
ITEM-ID(3文字)がある - それぞれに
ITEM-NAME(10文字)がある IDXは「今どのITEM-RECを見ているか」を指すための指さし棒
番号じゃなくて位置だ。
そして、SET IDX TO 1の意味だが、「IDXに数字1を入れる」のではなくて、「IDXを1番目のITEM-RECに向ける」だ。
な)ってことは、ここで「数字」って考えたらダメだと。
係)そう。IDXは矢印だと思え。
ここまでが前提だ。
SEARCHの中身:PERFORMを糖衣で包んだだけ
そして、ここからがSEARCHの本体となる。
SEARCH ITEM-REC
これを日本語にするとこうなる。
「IDXが指している位置から、ITEM-RECを順番に見ていく」
な)え、ITEM-RECって「探す対象」じゃないんすか?
係)探す“箱”だな。その条件はWHENに書いてある。
AT ENDとWHENの役割は、
WHEN
- 条件一致したとき
- 1回だけ実行
- 見つかったら
SEARCH終了
AT END
- 最後まで見つからなかったとき
- ここも1回だけ
な)複数件ヒットは?
係)できない。
SEARCHは「最初の1件」を探す命令だ。
そして、なぜSUBSCRIPTが使えないかということだ、SEARCHは、
INDEXを自動で動かすSET UP BYを内部で使う
だから、数値(SUBSCRIPT)では構造が合わないから、仕様的にNGとなる。
な)なんかSEARCH使う意味あるんすか?
係)正直に言うとだな。
使いどころとしては、
- 「1件だけ探す」
- 「
INDEX前提の設計」 - 「
SEARCH ALLを使う前段」
使わなくていい場面は、
- 集計
- 全件処理
- ロジックが複雑
つまり、PERFORMが書けるなら無理に使うなってことだ。
まとめると、
SEARCHはOCCURS+INDEX専用- 上から順に1件探すだけ
- 内部は
PERFORM+SET SUBSCRIPTは使えない- 読みやすいが、万能ではない
ということだな。
おむすび
な)やっとやっと長過ぎる行が終わるんすね…感動のエンディングロールが見れるんすね…。係長の興奮度合いから、ここまで風呂敷広げるとは思わなかったすよ。東京ドーム何個分すか。ほんと。
係)…引っかかる言い方だな…
ま、つまり、SEARCHは「INDEX付きPERFORMの糖衣構文」と言えるな。
な)はあ?
係)なんだよ。
な)なんで余計なこと言うんすか!?
係)え!?
係長のワンポイント
SEARCH は「探す命令」じゃない。INDEXを前に進めながら条件を一つずつ当てる構造だ。
だから数(SUBSCRIPT)は使えず、位置(INDEX)だけが許される。
魔法に見えるのは、内部が隠されているからにすぎない。SEARCHを理解する鍵は、命令より前提を読むことだ。

コメント