C++ などの他のプログラミング言語では、インクルード ガードを使用して、同じコードが複数含まれないようにします。
C++ では次のようになります。
#ifndef FOO_INCLUDED
#define FOO_INCLUDED
....
#endif
SAS マクロ関数の定義に包含ガードを組み込むことは理にかなっていますか? そして、それはどのように行われるべきですか?
C++ などの他のプログラミング言語では、インクルード ガードを使用して、同じコードが複数含まれないようにします。
C++ では次のようになります。
#ifndef FOO_INCLUDED
#define FOO_INCLUDED
....
#endif
SAS マクロ関数の定義に包含ガードを組み込むことは理にかなっていますか? そして、それはどのように行われるべきですか?
%SYMEXIST(macro-var-name)
マクロ変数が存在するかどうかを確認するマクロ関数がありますが、オープンに書き込むことはできないため、ステートメントを他のマクロで%IF
囲む必要があります。%IF
以下のように、コードをソースファイルにラップするためだけにマクロを書くことになるかもしれません。これはきれいではありませんが、ガードが必要な場合は、おそらくこれでうまくいくでしょう。
%macro wrapper;
%if %symexist(foo_defined) %then %return;
%macro foo;
%global foo_defined;
%let foo_defined = 1;
%put i am foo;
%mend foo;
%mend wrapper;
%*-- tests --*;
options mcompilenote=all;
%symdel foo_defined;
%*-- first time it will define %foo --*;
%wrapper
%foo
/* on log
NOTE: The macro FOO completed compilation without errors.
6 instructions 108 bytes.
i am foo
*/
%*-- second time it will not --*;
%wrapper
%foo
/* on log
(no notes on macro compilation)
i am foo
*/
起動すると、SAS は、(コンパイル済み/コンパイルされていない) マクロにアクセスするための一連のカタログ、ファイル、およびディレクトリを利用できるようにします。これにより、マクロの名前が与えられたときに、マクロがこのセッションで既に使用可能かどうかを直接確認するのは面倒ですが、不可能ではありません。このホワイト ペーパーの (残忍な) 詳細については、 http ://support.sas.com/resources/papers/proceedings09/076-2009.pdf を参照してください。
NOMREPLACEオプションを使用して、マクロが再定義されないようにすることができます。
私の意見では、マクロ名とマクロ変数名(さらにはデータセット名)を再利用することは悪です。一度だけ定義すれば、コードの任意の部分を再送信して、元の結果と同じ結果が得られることを比較的確信できます。また、マクロ定義を呼び出し元のコードとは別にしておくことも好みます。