2019年3月1日金曜日

luaでプログラムをループさせる話

luaでプログラムをループさせると言う試みです.
今までSASではマクロがその役割を担ってきましたが,luaでも出来ますよと言う紹介です.

以下に載せているのは,workにある3つのデータセット(tst tst1 tst2)の更新日時をログに表示するプログラムです.
マクロで書く場合とまったく同じ結果が得られますし,マクロで書くより実行ログが見やすいです.

繰り返しの対象となったプログラムのコードがログに表示されますし,luaのテーブルで与えた可変の情報が代入された状態でログにSASコードが生成されます.
その分ログが長くなりがちですが,どこで何が代入されてプログラムが実行されているのかがログを見て一発でわかるのでとても修正がしやすいです.
マクロを使うと結局ここではマクロ変数に何の値が入っているのかを確認するのが煩雑だと思います.mprintとか駆使すればいけますが ,アレもいまいち見やすい形でログに表示されないのではないでしょうか.

なにはともあれ,下のプログラムと実行ログを見てみてください.
以下実行プログラム

data tst ;
a = 1 ;
run ;

data tst1 ;
a = 1 ;
run ;

data tst2 ;
a = 1 ;
run ;

proc lua terminate;
    submit ;

    -- ログ整理用ダミー
    sas.submit([[
        data _null_ ;
        run ;
    ]])

    dataset = {}
    dataset[1]  = "work.tst"
    dataset[2]  = "work.tst1" 
    dataset[3]  = "work.tst2" 

    for i, tag in ipairs(dataset) do
        sas.submit([[
            data _null_ ;
                RCO = open("@tag@") ;
                RC = attrn(RCO , "modte") ;
                CL = close(RCO) ;
                format RC e8601dt. ;
                putlog "@tag@:" RC ;
            run ;
        ]])
    end

    endsubmit;
run ;
/*実行ログ*/

2460   proc lua terminate;
2461       submit ;
2462
2463       -- ログ整理用ダミー
2464       sas.submit([[
2465           data _null_ ;
2466           run ;
2467       ]])
2468
2469       dataset = {}
2470       dataset[1]  = "work.tst"
2471       dataset[2]  = "work.tst1"
2472       dataset[3]  = "work.tst2"
2473
2474       for i, tag in ipairs(dataset) do
2475           sas.submit([[
2476               data _null_ ;
2477                   RCO = open("@tag@") ;
2478                   RC = attrn(RCO , "modte") ;
2479                   CL = close(RCO) ;
2480
2481                   format RC e8601dt. ;
2482                   putlog "@tag@:" RC ;
2483               run ;
2484           ]])
2485
2486       end
2487
2488       endsubmit;
2489   run ;
NOTE: Lua initialized.
        data _null_ ;
        run ;
NOTE: DATAステートメント処理(合計処理時間):
      処理時間           0.00 秒
      CPU時間            0.00 秒

            data _null_ ;
                RCO = open("work.tst") ;
                RC = attrn(RCO , "modte") ;
                CL = close(RCO) ;
                format RC e8601dt. ;
                putlog "work.tst:" RC ;
            run ;
work.tst:2019-01-12T20:01:32
NOTE: DATAステートメント処理(合計処理時間):
      処理時間           0.01 秒
      CPU時間            0.01 秒

            data _null_ ;
                RCO = open("work.tst1") ;
                RC = attrn(RCO , "modte") ;
                CL = close(RCO) ;
                format RC e8601dt. ;
                putlog "work.tst1:" RC ;
            run ;
work.tst1:2019-01-12T20:01:32
NOTE: DATAステートメント処理(合計処理時間):
      処理時間           0.00 秒
      CPU時間            0.00 秒

            data _null_ ;
                RCO = open("work.tst2") ;
                RC = attrn(RCO , "modte") ;
                CL = close(RCO) ;
                format RC e8601dt. ;
                putlog "work.tst2:" RC ;
            run ;
work.tst2:2019-01-12T20:01:32
NOTE: DATAステートメント処理(合計処理時間):
      処理時間           0.00 秒
      CPU時間            0.00 秒

NOTE: TKLua terminated.
NOTE: PROCEDURE LUA処理(合計処理時間):
      処理時間           0.35 秒
      CPU時間            0.20 秒