
本記事は、「%ZLANGF00」ルーチンを利用して、オリジナル$z関数の作成方法をご紹介します。
はじめに
「共通関数を実行する際、クラス名.関数名()で実行すると冗長的だな」とか「スーパークラスに組み込むと煩雑になるな」とか思ったことはありませんか?
そんな時は、オリジナルの$z関数を作成してみるのも一興です。
この記事では、%ZLANGF00ルーチンの概要、活用方法、注意点について具体的に解説していきます。
%ZLANGF00とは
「%ZLANGF00」ルーチンは、3つある「%ZLANG」ルーチンシリーズの1つになります。
関数のFunctionの頭文字「F」をルーチン名に冠している様に、オリジナルの$z関数を設定する事ができます。
ベース作成
先ずは新規ルーチンの名前を「%ZLANGF00.mac」とし、下記を貼り付けてください。
%ZLANGF00 ;
q
;-
;
これで一先ずベースは完了です。
次は、オリジナルの$z関数を作成しましょう。
オリジナルの$z関数を作成する
では、オリジナルの$z関数を作成したいと思います。
今回作ろうと考えているのは、$horologの値を「YYYY/MM/DD」形式に変換する関数にしたいと思います。
割とこの日付形式は利用される割には、$ZDATEのdformatに候補が無いんですよね。
無いのであれば、この際作成しちゃいましょう!
サンプルは下記になります。
%ZLANGF00 ;
q
;-
;
ZSDATE(h) public {
q $tr($zd(+h, 3),"-", "/")
}
やっている事は、「YYYY-MM-DD」に変換して「-」を「/」に$TRANSLATEしているだけです。
では、ターミナルで動作を確認してみましょう。
ネームスペースはいつもの「SAMPLE」で行いたいと思います。

$horologの値を引数とし、「YYYY/MM/DD」に変換された事を確認しました。
では、「USER」ネームスペースではどうでしょうか?

いいですね!
10日前の日付を「YYYY/MM/DD」形式で出力する事が出来ました。
簡単な関数ですが、オリジナルの$z関数を作成する事ができました。
便利な関数等をオリジナル%z関数にする事で、全体のコーディング量を減らすことが可能になると思います。
ただし、注意が1点あります。
同一のインスタンスで他社システムと相乗りする場合、同じ「$LANGF00」ルーチンも相乗りで記述する事になります。
関数の名称が被る事だけは注意が必要になります。
処理速度を検証する
例えコーディング量が減ったとしても、処理が異常に遅くなってしまっては本末転倒です。
通常の処理とオリジナル関数とで、処理速度の差を検証してみましょう。
検証してみる
同じ処理を関数化して検証してみます。
ClassMethod cnvDate(h As %Date) As %String
{
q $tr($zd(h, 3),"-", "/")
}
下記をターミナルに張り付けて速度検証を行ってみます。
Check(cnt) ;
s start=$zh
f pos=1:1:cnt {
s d=$zsdate($h)
}
w "オリジナル:"_($zh-start),!
// 通常の関数
s start=$zh
f pos=1:1:cnt {
s d=##class(developer.Sample).cnvDate(+$h)
}
w " 通常:"_($zh-start),!
では、下記コマンド実行して検証開始です。
d Check(1000000)
【実行結果(100万回ループ)】
オリジナル:3.059877
通常:2.495885
・
・
・
えぇ!? 遅せぇ?
コントみたいな落ちになってしまいました。
ドキュメントにある下記記載はこの事を指すんですねぇ・・・
^%ZLANG 機能の実行速度は標準の InterSystems IRIS 機能ほど速くありません。
パフォーマンスが重要なルーチンをコーディングする際には、この点を考慮してください。
んー・・・実行回数から見たら些細な差ですが、どう判断したものか(汗
続・検証してみる
処理が遅いのは認識しました。
では、次は、「呼び出し」が遅いのか、「処理自体」が遅いのか切り分けたいと思います。
両者を下記修正して検証です。
※developer.Sample.clsも同様の処理を行いました。
ZSDATE(cnt) public {
s h = $h
s start = $zh
f pos=1:1:cnt {
s val = $tr($zd(h, 3),"-", "/")
}
q ($zh - start)
}
では、改めて検証です。
Check2(cnt) ;
w "オリジナル:"_$zsdate(cnt),!
w " 通常:"_##class(developer.Sample).cnvDate(cnt),!
では、下記コマンド実行して検証開始です。
今回は、1,000万回のループで確認してみます。
d Check2(10000000)
【実行結果(1,000万回ループ)】
オリジナル:2.669659
通常:2.767437
1,000万回の実行で0.1秒の差であれば、誤差と言っても過言ではないですね。
何回か繰り返しても、結果はあまり変わりません。
検証結果からみると、「%LANGF00」ルーチンの呼び出しに時間が掛かっているようです。
コーディングが楽になる代わりに、呼び出し時間に僅かな時間差がでる・・・う~ん、悩ましいですね。
おわりに
いかがだったでしょうか。
今回は、オリジナルの$z関数の自作という、夢のような機能のご紹介でした。
ただ、関数の呼び出し時間が、通常の関数より若干遅いという弱点があります。
ひたすらに速度を追い求める様なシステムであれば、相性が悪いでしょう。
また、他社とのシステム相乗り時にも注意が必要です。
ただ、それらを乗り越えた先に、ロマン溢れるオリジナル関数が待っています!
%ZLANGF00ルーチンを活用して、効率の良いコーディングを目指してみませんか?