5

マクロ変数のスコープに関連する問題を解決しようとしているときに、この非常に役立つ SO ページを見つけました。 %let がローカル マクロ変数を作成しないのはなぜですか?

要約すると、%let x = [];または%do x = [] %to [];マクロで記述すると、次のようになります。

  • グローバル シンボル テーブルに「x」が存在しない場合は、ローカル スコープのマクロ変数 x を作成します。または、
  • 「x」がグローバルシンボルテーブルにある場合、グローバルスコープマクロ変数「x」を更新します

これは非常に非直感的だと思います。この設計の選択により、SAS の荒野に大量のバグが発生していることは間違いありません。「i」や「counter」などの一般的な変数名を使用するループ ステートメントの上であっても、マクロで %local ステートメントを目にすることはめったにありません。たとえば、SUGI および SAS グローバル フォーラムの論文のリストから、タイトルに「マクロ」という単語が含まれる最初の論文を見つけました 。 =スギ

実際、私が開いた最初の SAS カンファレンス ペーパーでこのコードを見つけました。

%macro flag;
data CLAIMS;
 set CLAIMS;
 %do j= 1 %to 3;
 if icd9px&j in (&codelist)
 then _prostate=1;
 %end;
run;
%mend;
%flag;

http://support.sas.com/resources/papers/proceedings15/1340-2015.pdf

%flag を呼び出し、独自の &j 変数を持っている人は悲惨です。%flag を呼び出した後、どこでも &j が 4 になるため、ログ エラーは発生せず、偽の結果が簡単に発生する可能性があります。これは (経験上) 追跡するのが楽しくないバグになります。さらに悪いことに、彼らは自分の結果が偽物であることを決して認識しないかもしれません.

だから私の質問は、すべてのマクロ変数をデフォルトでローカルスコープにしないという決定がなされたのはなぜですか? SASマクロ変数のスコープがそのように機能するのには、正当な理由がありますか?

4

3 に答える 3

4

主に、SAS は字句スコープが明らかに好まれる前に存在していた 50 年前の言語であるためです。

SAS には 2 つのスコープの概念が混在していますが、意図的に変更しない限り、ほとんどの場合動的にスコープが設定されます。これは、関数の定義を読んだだけでは、実行時にどの変数を使用できるかがわからないことを意味します。割り当てステートメントは、実行時に現在使用可能な変数のバージョンに適用されます (使用可能な最もローカルなスコープに強制されるのではなく)。

つまり、マクロ コンパイラは、特定の割り当てステートメントがローカル マクロ変数を割り当てることを意図しているのか、それとも実行時に存在する可能性のあるより高いスコープのマクロ変数を割り当てることを意図しているのかを判断できません。あなたが述べたように、SASはローカルマクロ変数を強制することができますが、それはSASをレキシカルスコープ言語に変えます。SAS はレキシカル スコープを強制する機能 ( use %local) を提供しますがparent%global.

ダイナミック スコーピングは 60 年代と 70 年代に非常に一般的であったことに注意してください。S-Plus、Lisp などはすべて動的スコープを持っていました。SAS は、可能な限り後方互換性を優先する傾向があります。また、SAS はプログラマーではなくアナリストとしても使用されることが多いため、可能な限り複雑さを避ける必要があります。これらは%local、字句スコープの利点を望んでいる私たちに提供します

于 2016-02-22T16:14:57.583 に答える
0

そうなると、少なくとも新しい宣言ステートメントがなければ、これを行うことはできませんでした。

33         %let c=C is global;
34         %macro b(arg);
35            %let &arg=Set by B;
36            %mend b;
37         %macro a(arg);
38            %local c;
39            %b(c);
40            %put NOTE: &=c;
41            %mend a;
42         %a();
NOTE: C=Set by B
于 2016-02-22T10:34:27.557 に答える