InterSystemsCachéのマクロ

オランダのモネチューリップ

はじめに


InterSystemsCachéでのマクロの使用について説明します。 マクロは、ソースコードを一連のプログラム命令でコンパイルするときに置き換えられる記号名です。 マクロは、マクロ内のトリガーされたブランチとそれに渡される引数に応じて、呼び出しごとに異なる命令シーケンスで「展開」できます。 これは、静的コードまたはCOS実行の結果のいずれかです。 アプリケーションでどのように使用できるかを検討してください。

編集



はじめに、マクロが使用されている場所を理解するために、ObjectScriptコードがどのようにコンパイルされるかについていくつか説明します。

マクロ


既に述べたように、マクロは、プログラム命令のシーケンスを備えたプリプロセッサによる処理中に置換される記号名です。 #Defineコマンドを使用して、最初にマクロ名を(おそらく引数のリストを使用して)、次にマクロ値を使用して決定します。
#Define Macro [( Args )] [Value]
マクロはどこで定義できますか? コード内で直接、またはマクロのみを含む別のINCファイルで 。 クラス定義の最初にあるMacroFileNameを含むコマンドを使用して、必要なファイルをクラスに接続します-これは、マクロをクラスに接続するための主要かつ推奨される方法です。したがって、クラス定義の任意の部分でマクロを追加できます。 #Include MacroFileNameコマンドを使用して、INCマクロファイルをMACルーチンまたは個々のクラスメソッドのコードに添付できます。


例1


使用例に移り、「Hello World」の行の出力から始めます。 COSコード: 「Hello、World!」と 書く
次の行を表示するHWマクロを作成します。 #define HW Write "Hello、World!"
コードに$$$ HWを記述するだけです( $$$マクロを呼び出してから、マクロ名):

ClassMethod テスト()
{
#define HW 「Hello、World!」と 書く
$$$ HW
}

コンパイル時に、次のINTコードに変換されます。

zTest1 public {
「Hello、World!」と 書く }

ターミナルでは、このメソッドが起動されると、以下が表示されます:
Hello, World! 

例2


次の例では、変数を使用します。

ClassMethod Test2()
{
#define WriteLn(%str、%cnt) For ## Unique(new)= 1:1:%cnt {## Continue
%strを書きます! ##続行
}

$$$ WriteLn "Hello、World!" 、5)
}

ここでは、string%strが%cnt回表示されます。 変数名は%で始まる必要があります。 ## Unique(new)コマンドは、生成されたコードに新しい一意の変数を作成し、 ## Continueコマンドを使用すると、次の行でマクロの定義を続行できます。 このコードは、次のINTコードに変換されます。

zTest2 public {
%mmmu1 = 1:1:5の場合{
「Hello、World!」と 書く
} }

ターミナルでは、このメソッドが起動されると、以下が表示されます:
 Hello, World! Hello, World! Hello, World! Hello, World! Hello, World! 

例3


さらに複雑な例に移りましょう。 ForEach演算子は、グローバルを反復処理するときに非常に便利です。追加します。

ClassMethod Test3()
{
#define ForEach(%key、%gn) Set ## Unique(new)= $ name(%gn)## Continue
Set%key = "" ##続行
{##続行
Set%key = $ o(@ ##一意(古い)@(%key))##続行
終了:%key = ""

#define EndFor }

セット ^テスト(1)= 111
セット ^テスト(2)= 222
セット ^テスト(3)= 333

$$$ ForEach キー 、^テスト)
「key:」 key 、!
「value:」 、^ test( key )、!
$$$ EndFor
}

INTコードでは次のようになります。

zTest3 public {
セット ^テスト (1)= 111
セット ^テスト (2)= 222
セット ^テスト (3)= 333
%mmmu1 = $ nameを 設定 ^テスト)
キーを 設定 = ""
{
キーを 設定 = $ o @ %mmmu1 @key
終了 key = ""
「key:」 key 、!
「value:」 ^ test( key 、!
} }

これらのマクロはどうなりますか?

ターミナルでは、このメソッドが起動されると、以下が表示されます:
 key: 1 value: 111 key: 2 value: 222 key: 3 value: 333 

リスト配列( %Collection.AbstractIteratorクラスの子孫)を使用する場合は、同様のイテレーターを既に作成できます。

例4


マクロのもう1つの可能性は、コンパイル段階で任意のCOSコードを実行し、実行結果をマクロの代わりに置き換えることです。 コンパイル時間のあるマクロを作成します。

ClassMethod Test4 ()
{
#Define CompTS ## Expression( "" "Compiled:" _ $ ZDATETIME($ HOROLOG)_ "" "、!"
$$$ CompTSを書く
}

これは、次のINTコードに変換されます。

zTest4 public {
「Compiled:05/19/2015 15:28:45」と書きます! }

ターミナルでは、このメソッドが起動されると、以下が表示されます:
 Compiled: 05/19/2015 15:28:45 

##式はコードを実行し、結果を置き換えます;次のCOS言語要素を入力できます:

例5


プリプロセッサディレクティブ# If# ElseIf# Else# EndIfは、このメソッドのように、ディレクティブの後の式の値に応じて、コンパイル時にソースコードを選択するために使用されます。

ClassMethod Test5()
{
#If $ SYSTEM .Version GetNumber ()= "2015.1.1" && $ SYSTEM .Version GetBuildNumber ()= "505"
「Cachéの最新リリースバージョンを使用しています」と 書く
#ElseIf $ SYSTEM .Version GetNumber ()= "2015.2.0"
「Cachéの最新ベータ版を使用しています」と記述します
#その他
「アップグレードを検討してください」と 書いて ください
#EndIf
}

Cachéバージョン2015.1.1.505では、次のINTコードがコンパイルされます。

zTest5 () public {
「Cachéの最新リリースバージョンを使用しています」と 書く
}

そして、ターミナルで出力されます:
 You are using the latest released version of Caché 

ベータポータルからダウンロードされたCachéは、別のINTコードにコンパイルされます。

zTest5 () public {
「Cachéの最新ベータ版を使用しています」と記述します
}

そして、ターミナルで出力されます:
 You are using the latest beta version of Caché 

また、Cachéの以前のバージョンは、アップグレードの提案とともに以下のINTコードをコンパイルします。

zTest5 () public {
「アップグレードを検討してください」と 書いて ください
}

そして、ターミナルで出力されます:
 Please consider an upgrade 

この機能は、たとえば、新しいバージョンのCachéDBMS機能を使用できる古いバージョンと新しいバージョンの間でクライアントアプリケーションの互換性を維持するために使用できます。 マクロの有無をそれぞれ確認するプリプロセッサディレクティブ#IfDef#IfNDefも、この目的に役立ちます。

結論


マクロは、コードを理解しやすくするだけでなく、コード内で頻繁に繰り返される構造を単純化するか、コンパイル段階でアプリケーションロジックの一部を実装して実行時の負荷を軽減することができます。

次は?


次の記事では、マクロを使用したより応用された例、ロギングシステムについて説明します。

参照資料


コンパイルについて
プリプロセッサディレクティブのリスト
システムマクロのリスト
例付きのクラス
パートII ロギングシステム

著者はhabrayuzersのDaimorGreyder 、そしてコードの作成に協力してくれた匿名のままにしたいと思っていた別の有能なエンジニアに感謝しています。

Source: https://habr.com/ru/post/J258081/


All Articles