【IRIS/Cache】オリジナルの特殊関数、コマンドを作成しよう!(%ZLANGV00,%ZLANGC00)

本記事は、「%ZLANGV00」「%ZLANGC00」ルーチンを利用して、オリジナルの特殊変数やコマンドを作成する方法をご紹介します。

※この記事は下記の方向けになります。
  • オリジナルの特殊変数を作成したい方
  • オリジナルのコマンドを作成したい方

はじめに

前回の記事で「%ZLANGF00」ルーチンのご紹介をしました。

本記事では、「%ZLANG」ルーチンシリーズの残り2つ、「%ZLANGV00」と「%ZLANGC00」について解説します。

「%ZLANGV00」はオリジナルの特殊変数を作成するルーチンであり、「%ZLANGC00」はオリジナルのコマンドを作成するルーチンです。

これらを活用することで、アイデア次第でコーディングを効率化できます。ただし、呼び出し速度が若干遅いというデメリットもあります。

メリットとデメリットを把握しつつ、適切に使いこなせば選択肢の一つとして活用できると思います。

では、それぞれの詳細について解説していきます。

%ZLANGV00

「V(variable)」とついている通り、オリジナルの特殊変数を作成します。

特殊変数については、常々よく利用していると思います。

特殊変数の一覧

特殊変数名説明
$HOROLOG現在のプロセスのローカル日付と時刻
$JOB現在のプロセスのジョブ ID
$NAMESPACE現在のネームスペース名
$TLEVEL現在のトランザクションの入れ子レベル
$USERNAME現在のプロセスのユーザ名
$ZHOROLOGシステム起動時以降の経過秒数
$ZJOB現在のプロセスのジョブの状態
$ZPI円周率
$ZTIMESTAMP協定世界時 (UTC) 形式による現在の日付と時刻
$ZTIMEZONEGMT を基準にしたローカル・タイム・ゾーン・オフセット
$ZVERSION現在のバージョン
$IOデバイスID

これらは、多々ある特殊変数の一部です。

では次は、これらと同様の特殊変数を作成していきます。

作成

「%SYS」ネームスペースにて、「%ZLANGV00」ルーチンを作成します。

今回は下記2つの特殊変数をサンプルで作成します。

  • 苗字を格納 & 返す
  • 本日の日付を「YYYY-MM-DD」で返す

サンプル

%ZLANGV00	;
	q
	;-
	;
	;-- 苗字を保存 & 返す
ZSEI(val)	;
	i ($d(val)) {
		s ^||testSei=val
	}else{
		q $g(^||testSei)
	}
	;-
	;
	;-- 本日の日付をYYYY-MM-DDで返す
ZNDATE	;
	q $zd($h, 3)
	;-
	;

では、ターミナルにて出力してみたいと思います。

今回作成した特殊変数「$zsei」は、引数をプロセス・グローバルに保存し、呼び出しの度にプロセス・グローバルの値を返す方法を採用しています。
 ※プロセス・変数やグローバル等でも代用可能です。

特殊変数の作成と使用方法は以上になります。
次は、特殊コマンドの解説を行います。

%ZLANGC00

「C(command)」とついている通り、オリジナルのコマンドを作成します。

オリジナルのコマンド?

と聞いても、イマイチ「ピン」と来ないかと思うので、実際にルーチンを作成しつつ動作を確認してみましょう。

作成

「%SYS」ネームスペースにて、「%ZLANGC00」ルーチンを作成します。

今回は、ネームスペース「%SYS」と「SAMPLE」に関数を用意し、その関数を実行するオリジナルのコマンドを作成して、%ZLANGC00の理解を深めたいと思います。

【サンプルルーチン】
ZADDFUJIコマンドは、ルーチン内のサブルーチンを実行しています。
ZSAMPLEコマンドは、ネームスペース「SAMPLE」に存在しているクラスを実行しています。

%ZLANGC00
	q
	;-
	;
ZADDFUJI(val)
	w $$ADDFUJIWARA(val) // ↓のラベルを呼ぶ
	;-
	;
ADDFUJIWARA(val)
	q "藤原"_val
	;-
	;
ZSAMPLE
	// 実行ネームスペースにあるクラスを呼ぶ
	d ##class(developer.Sample).callName()
	q
	;-
	;

ネームスペース「SAMPLE」にある関数「callName()」

ClassMethod callName()
{
	w "藤原道長"
}

では、実行ネームスペースを「SAMPLE」に変更し、各コマンドを実行してみましょう。
コマンドは下記になります。

zn "sample"

zaddFuji "道長"
zsample

実行結果が下記になります。

では、実行ネームスペースを「USER」に変更し、コマンドを実行したら、どのような結果が返ってくるでしょうか。

予想通り、コマンド「ZSAMPLE」はエラーになりましたね。
実行クラスがネームスペース「SAMPLE」に存在しているため、さすがに実行は難しいようです。

もし、他ネームスペースで実行したい場合は、特殊変数「$namespace」を使用してネームスペースを切り替える必要があります。

ZSAMPLE
	new $namespace
	s $namespace = "sample"
	d ##class(developer.Sample).callName()
	q
	;-
	;

コマンド「ZADDFUJI」に関しては、ルーチン「%ZLANGC00」がネームスペース「%SYS」に存在しているためか、どのネームスペースでも実行可能です。

どのネームスペースでも実行させたいのであれば、「%SYS」に処理を配置しておいた方が楽ですね。

速度検証

前回の記事からも、結果は予測できていますが、念のため速度検証を行いたいと思います。

下記をルーチンに張り付けて、検証を実施してみます。

Check(cnt)	;
	s start = $zh
	f pos=1:1:cnt {
		zsample
	}
	w "オリジナル:"_($zh-start),!
	
	s start = $zh
	f pos=1:1:cnt {
		d ##class(developer.Sample).callName()
	}
	w "   通常:"_($zh-start)

下記が実行コマンドになります。

d Check(1000000)

【実行結果(100万回ループ)】
オリジナル:1.962925
   通常:1.028507

呼び出しが遅いのは、前回の記事でも書いた通りです。
一回の実行速度は「0.000001」程度の差ですが、実行回数が増加すればその差は無視できなくなります。

アイディア・コーディング量を選択するか、処理速度を優先するかは、システムの性格にもよるので、検討をお願いいたします。

おわりに

いかがだったでしょうか。

全2回にわたり、3つの%ZLANGルーチンについて解説しました。

全体的な印象としては、「コーディング量を減らせる一方で、呼び出し時間が増加する」という、少し惜しい機能といえます。

しかしながら、アイデア次第では大きく活用の幅が広がる可能性を秘めています。

もし、「こんな使い方をしている」といった事例がありましたら、ぜひご連絡いただければ幸いです!