みなさん、こんにちは。

前回、一応完成した fl マクロを、さらに機能拡張したいと思います。第7回の最後に、さりげなくこんなコマンドを入力しました。

この時は、一切の説明抜きで紹介しましたが、#fileinfo built-in function はLASTOPEN_GMT 以外にも時刻に関するオプションを持っています。

    LASTOPEN_GMT 最終オープン日時
    CREATION_GMT ファイル作成日時
    MODIFICATION_LCT 最終更新日時

最後の MODIFICATION_LCT は日本なら JST ですね。LASTOPEN_GMT は GMT で、CREATION_GMT も同じく GMT です。今のところ fl は最終オープン日時だけを表示していますが、他の時刻も表示できるようにしたいところですね。これを第一の改修点とします。

では仕様を考えましょう。3つの時刻を全部一度に表示してもいいのですが、ミリ秒まで表示しているので横 80 文字に入りきれません。ここは fl マクロもオプションをつけて切り替えるようにします。仕様は……

としましょう。

もう1つ検討したい点があります。fl マクロを試しているうちに、fileinfo っぽく……

とか……

とか……

とかやってみたくなりませんでしたか。現在の仕様では単独の実在ファイルしか指定できません。複数のファイルを表示できませんし、存在しないファイルを指定したときのエラーメッセージも怪しすぎます。そこも改良してみましょう。これを第2の改修点とします。これらの修正では fl マクロを routine で実装してみます。macro のままでも対応は可能ですが、第一回で触れたパラメータチェック機能を堪能することにしましょう。

ではソースを修正します。あ、いや、まだ早いかな。routine を使うためには今まで紹介していないいくつもの要素が必要になります。fl を修正する前に、routine を使うときのお作法を身につけておくことにしましょう。 サンプルとして routineX というマクロを作ってみましょう。これを使ってroutine のお作法を説明していきます。 マクロソースの最後に次の routine を追加し、load してみてください。

今のところは特に何をするわけてもなく、パラメータを取り込むだけの機能しかありません。何はともあれ実行してみましょう。

何も起きません。

問題ありませんね。

おっと何かメッセージが印字されました。

これが routine のパラメータチェック機能による処理結果です。“^” という記号が “parameter”のところに表示されていますね。“parameter” というパラメータが、この routine にとっては望ましくないバラメータであるという意味です。 ソースファイルに戻ってみましょう。#argument という built-in function がありますね。これはroutine でパラメータを取り込むための関数です。routine では macro の時の %1% などの指定は使えず、 #argumentを使います。/ と / で囲まれた部分に value オプションが指定されていますので、パラメータの値が prm1 variable に取り込まれます。そしてその後ろには FILENAME END と記述されています。これは……

prm1 variable に取り込めるのは FILENAME あるいは END だけ

という意味です。END というのは「パラメータの最後」ということで、正確に言うと「パラメータなし」という意味になります。

と入力したとき、$SYSTEM.SYSTEM.TACLCSTM は FILENAME(=実在するファイル名)として正しいのでエラーにならず、prm1 に $SYSTEM.SYSTEM.TACLCSTM という値が取り込まれました。

としたときは END の方が効いたのでこれまたエラーにはなりません。ただしprm1 には END(=パラメータなし)が取り込まれるので、値としては何も取り込まれません。

この FILENAME とか END とかを alternative と言います。今の routineX は alternative として FILENAME と END だけ記述していますので FILENAME としては不正な “parameter” という文字列を与えると「FILENAME か END を期待していますよ」というメッセージを画面に出力して実行を停止します。これが routine のパラメータチェック機能です。ユーザロジックゼロでチェック機能を実装できます。

最終的な目的は……

の実現なので、試しに……

と入力してみましょう。うーん、残念ながらエラーですね。

ということで、 / のところに「ファイル名を期待しています」と表示されています。 / を使いたいなら、/ に相当する alternative を指定しなければならないのです。そこでこうします。

これで……

がエラーにならずにすみます。

それはいいのですが、この時 prm1 には何が格納されているでしょうか。答えは / の一文字だけです。今の段階では routineX / までしか処理されておらず、その後ろの open/ macsrc は無視されているのです。#argument では要素を1つずつしか取り込めません。routineX /open/ macsrc というコマンド文字列は、TACL 的には5つの要素で構成されています。

    1 ….. routineX
    2 ….. /
    3 ….. open
    4 ….. /
    5 ….. macsrc

1 はもちろんマクロ名であり routine 型の variable です。2 ~ 5 がパラメータ要素で、上記のソースでは最初の / だけを取りこんでいます。後ろに続く要素の取り込みについては次回やります。ここでは 3 の open についてだけ考えておきましょう。パラメータである要素 2 ~ 5 のうち、2,4 は SLASH alternative で取り込めます。5 は FILENAME alternative です。では 3 の open はどうでしょうか。フリーテキストとして取り込むこともできますが、今回 fl マクロのオプションは open,create,mod の3種類だけと決めました。こういうケースはKEYWORD alternative を使うのが便利です。こんな感じです。

KEYWORD alternative に WORDLIST オプションをつけて選択肢を絞っています。この機能をうまくつかうことで……

の3つしか受け付けなくなります。

どうてすか。ここまで付いてこられていますか?では元の FILENAME alternative に戻して、別の観点から解説します。ソースを次のように改修します。

さきほどと同じように実行してみましょう。

さきほども説明した通り、prm1 variable にはパラメータが格納されていますね。それでは val variable に格納された “1” は何なのでしょうか。

    #set val [#argument/value prm1/FILENAME END]

としていますので、これは #argument built-in function の戻り値です。何番目の alternative にヒットしたかを返してくれているのです。今回は1番目が FILENAME で2番目が END ですから、入力したパラメータが FILENAME に該当する場合は #argument は1を返します。END なら2ですね。試してみましょう。

「ガッテン!」いただけましたでしょうか。

次回も routineX の話が続きます。Au revoir!