proc Luaの世界③SASコードを実行する話 四六時中遊べる異常な面白さ間違いなし!!

いよいよproc Luaの中でSASコードを実行する話です。多分これも後にさらに掘り下げて
記事を書くと思いますが、とりあえず触りです。

まず以下のコードを実行します

proc lua;
 submit;
  --sas.set_quiet(true) 実行されるコードをログにださない場合:マクロのnomprintみたいなもん
  sas.submit([[data a;x=1;run;]])
endsubmit;
quit;








こんな感じです、ログに実行されたSASコードがでて、実行されます。
マクロと違ってデフォルトでは、実行された実際のコードがログに出力される設定sas.set_quiet(false )になってます。
nomprintのように実行コードをログにだしたくない場合はsas.set_quiet(true )としましょう。

sas.submit([[ SASコード ]])が基本の書き方になります。sas.submtのタイミングで記述したSASコードがsubmitされます。

次に以下のコードをみてください。

proc lua;
 submit;
 local code=[[data a;x=1;run;]]
 sas.submit(code)
endsubmit;
quit;

結果は同じです。つまり一旦変数の中にSASコードを格納し、それをsas.submitで指定することでも同じことになります。

Luaのテーブルは柔軟なので、例えば再利用性の高い処理であれば
カテゴリでまとめたりしてテーブルにいれて、

proc lua ;
 submit;
 makeds={} --グローバルでテーブルmakedsを作って、その中にコードを入れている
 makeds.mds1=[[data ds1;x=1;run;]]
 makeds.mds2=[[data ds2;x=1;run;]]
 makeds.mds3=[[data ds3;x=1;run;]]
endsubmit;
quit;

以下のように使いたい時に取り出して実行することができます。

proc lua ;
 submit;
 sas.submit(makeds.mds2) --makdedsテーブル内のmds2のコードが実行される
endsubmit;
quit;

以前の記事で、グローバルで定義したものはnilを代入しないと消えないといった話をしたのですが
あれはどうやら、ちょっと間違いです。

proc luaの後にrestartと記述すると一旦、Luaの環境をリセットし、グローバル定義も全て初期化されます。
つまり、以下のコードを実行すると

proc lua restart;
--[[restartは記述したproc lua開始時点で一旦Luaの環境をリセットしてメモリ上に滞留してるグローバル変数などを全部殺すよ]]--
--terminateは記述したproc luaが終わった時点でリセットするよ
 submit;
 sas.submit(makeds.mds2) --makdedsテーブル内のmds2のコードが実行される
endsubmit;
quit;

makedsはnilに初期化されているので参照エラーになります

ちなみにproc lua terminateとすると、そのprocが終わるまでは環境が保持されてますが、終わる時点でリセットがかかります。restartとのタイミングの違いに注意しましょう。

つづいて、マクロパラメータのように、可変的部分を実行時に与えて実行する方法について紹介します。

以下のコードを実行すると
proc lua;
 submit;
 --置換(可変)部分を@で括って定義できる
 local code=[[data @ds@;
              @var@=1;
             run;]]
 --実行時に置換パラメータを指定して実行する
 sas.submit(code,{ds="b",var="y"})
endsubmit;
quit;











となります。
実行時に置換される部分を@置換変数@と書いて定義しておき、実行時に
sas.submit([[SASコード]] ,{置換変数1= , 置換変数2= ,,,, })として実行します。

さて、次に話です。call executeのように、実行するSASコードを刻んでいきたい場合、つまり
sas.submit_([[data c;x=1;run;]])を、

sas.submit_([[data c;)]]
sas.submit_([[x=1;)]]
sas.submit_([[run;)]]
としたいな~って思った場合、そのままだとエラーになります。
なぜかというと、submitすると、そこを部分実行したのと同じで
x=1;というのだけ実行しても、それはエラーですよね。
ちなみに、data c;の部分は暗黙的runが補完されたような形になって一応動きますけど。

さて、ではどうすればいいのかという話ですが、
subimit_と、アンダースコアをつけるのです。
subimit_で実行されたコードは、submitとアンダースコア無しのsubmitが実行されるまでは
ストックされた状態で、待機したような形になります。

proc lua;
submit;
 sas.submit_([[data c;]]) --submit_とアンダースコアがついてることに注意!
 sas.submit_([[x=1;]])    --アンスコなしのsubmitが実行されるまでアイドリング状態になる
 sas.submit([[run;]])     --ここで一気に実行される
endsubmit;
quit;

と書けるということです。

これが、何を意味するのかというと、Luaで実行するSASコードを可変的に
生成する場合、全文コードを生成してからsubmitしなくても純粋に可変部分のみ
で済むということ、すなわち!

proc lua;
submit;
 sas.submit_([[data d;]])
 for i = 1,4 do
  sas.submit_([[x=@val@;output;]],{val=i})
 end
sas.submit([[run;]])
endsubmit;
quit;

というコードが成立し、
ログに出ている実際に実行されたコードをみると以下のようになっています









まだまだ紹介したいことはあるんですが、とりあえずここまで!

面白い。僕は心から面白いと感じるんですけど、この感動、情動をどうやったらうまく表現できるのか。どうすれば流行らせられるか、次世代のスタンダードな知識にできるのか、いいアイデアがあれば是非教えて下さい



0 件のコメント:

コメントを投稿