stuncloud / UWSCR

UWSC互換スクリプト実行ツール
MIT License
50 stars 5 forks source link

UWSCR 0.16.1 モジュールをcallで呼び出す際の挙動について #142

Closed Patrick10731 closed 5 months ago

Patrick10731 commented 5 months ago

概要

UWSCR 0.16.1を使用しています モジュールを呼び出し時の挙動について修正してほしいことがあります

test1.uwsを起動した場合についてUWSCでは以下のように同じ名前のモジュールを複数回呼び出すことができます

----------test1.uws----------

call test_module.uws

testmodule.testproc()

call test_module2.uws

testmodule.testproc()

sleep(10)


----------test_module.uws----------

module testmodule

procedure testproc() print "モジュールテスト" fend

endmodule


----------test_module2.uws----------

module testmodule

procedure testproc() print "モジュールテスト2" fend

endmodule


-----結果------ モジュールテスト モジュールテスト

UWSCでは2回目に呼び出したモジュールは無視されているようです

UWSCR(0.14.0)ではこのコードは多重定義エラーになり動きませんが、以下のように書き換えれば動かすことができました なおこのコードはUWSCでは動きません

----------test1.uws----------

PUBLIC module_called_flag module_called_flag = False

call test_module.uws

testmodule.testproc()

module_called_flag = True

call test_module2.uws

testmodule.testproc()

sleep(10)


----------test_module.uws----------

if module_called_flag = False

module testmodule

procedure testproc() print "モジュールテスト" fend

endmodule

ELSE ENDIF


----------test_module2.uws----------

if module_called_flag = False

module testmodule

procedure testproc() print "モジュールテスト2" fend

endmodule

ELSE ENDIF


-----結果------ モジュールテスト モジュールテスト

無論、module_called_flag = Trueをコメントアウトすると多重定義でエラーになります

問題はUWSCR(0.16.1)の挙動で、上2つのコード両方ともエラーになります ifを使う場所を変えてみたり、try,exceptを使ってみてもやはり動きません

これによりUWSCとUWSCR(0.14.0)で従来使っていたコードを再現できなくなってしまっています 具体的に発生する問題ですが、私の使っているスクリプトは単独で起動することもありますし、callから呼び出して使うこともあります 呼び出し元、呼び出し先ともに自作関数を使うためどっちのプログラムもcallでモジュールを呼び出す必要があります、単独使用と呼び出しでの使用両方に対応させるためです この例ではtest_module.uwsとtest_module2.uwsを同じuwsファイルの中で呼び出していますが、実際は異なるuws(callでの呼び出し元と先)の中で、同じuwsファイルを呼び出しています ですが0.16.1にアップデート後に使えなくなってしまい困っております モジュールを最初の1回しか読み込まないコードが再現できればよいのですが… UWSCの仕様、0.14.0で使えていた仕様、または異なる実装どちらでも構わないのでエラーを回避できるようにしていただけないでしょうか?

再現スクリプト

UWSCで動かす場合
----------test1.uws----------

call test_module.uws

testmodule.testproc()

call test_module2.uws

testmodule.testproc()

sleep(10)

------------------------------

----------test_module.uws----------

module testmodule

procedure testproc()
print "モジュールテスト"
fend

endmodule

-----------------------------------

----------test_module2.uws----------

module testmodule

procedure testproc()
print "モジュールテスト2"
fend

endmodule

------------------------------------

-----結果------
モジュールテスト
モジュールテスト
---------------

UWSCR(0.14.0)で動かす場合
----------test1.uws----------

PUBLIC module_called_flag
module_called_flag = False

call test_module.uws

testmodule.testproc()

module_called_flag = True

call test_module2.uws

testmodule.testproc()

sleep(10)

------------------------------

----------test_module.uws----------

if module_called_flag = False

module testmodule

procedure testproc()
print "モジュールテスト"
fend

endmodule

ELSE
ENDIF

-----------------------------------

----------test_module2.uws----------

if module_called_flag = False

module testmodule

procedure testproc()
print "モジュールテスト2"
fend

endmodule

ELSE
ENDIF

------------------------------------

-----結果------
モジュールテスト
モジュールテスト
---------------

再現手順

No response

バージョン

0.16.1

不具合発生環境

Windows 10

stuncloud commented 5 months ago

UWSCの件はcallでの多重定義の考慮漏れによる不具合のような気がしますね

0.16.1での問題というのが文面から読み取れないのですが、こういうことでしょうか?

これに関しては仕様です 異なるmoduleに同一の名前を付けない、が根本的な問題の解消法になります UWSCでの同一module名があると一方が無視されるという動作は不具合であると判断し、そのような場合その動作をUWSCRで再現することはありません

これも仕様です
0.14の動作がバグです module定義はブロック内では行うことができない、が仕様となります

具体的なエラーを教えてください その上で何が問題となっているか教えてください 実装上の不備である可能性が高いです

Patrick10731 commented 5 months ago

回答ありがとうございます、その認識であっています 仕様とのことですね 0.16.1で動かした場合のエラーは以下の通りです

UWSC用のコード UWSCR実行時エラー test_module2.uws 2行目: module testmodule [モジュール定義エラー] testmodule は定義済みです

UWSCR 0.14.0用のコード UWSCR構文エラー test1.uws[4, 1] - call文で呼び出したスクリプトにエラーがありました test_module.uws[3, 1] - ブロック構文内では定義できません test1.uws[10, 1] - call文で呼び出したスクリプトにエラーがありました test_module2.uws[3, 1] - ブロック構文内では定義できません

・実装上の問題となっていること 単独で動作させているスクリプトをcallでまとめて動かすことできなくなっている 下のスクリプトは12時にtest1.uwsを自動起動し、13時にtest2.uwsを自動起動するプログラムの例です test1.uws、test2.uwsはモジュール読み込み用の同一uwsファイルを読み込み、ある処理を行うスクリプトです test1.uws、test2.uwsは単体でダブルクリックして起動させることも多いので、単体で起動できるように当該スクリプト内でのモジュールの呼び出しは必須です しかしそうしてしまうと、uwscr 0.16.1ではcallでの自動起動の運用ができなくなってしまいます また、このようなスクリプトを大量運用しているためスクリプトごとにモジュールの名前を変える、単体で起動するために別途スクリプトを用意する、というのは手間がかかるため避けたいと考えています

・要望 モジュールの上書きでも、2回目以降は無視でも、IFを適応可能にする形でも構わないので従来と同じように動かせるようにしてもらえないでしょうか? 現在のmoduleの仕様はそのままで、新たに上書き可能なmoduleと同等の動きをする関数実装という形でも構いません

WHILE TRUE

t2=GETTIME()

IF G_TIME_HH=12 and G_TIME_NN>=0 and 30>G_TIME_NN BREAK else endif

WEND

call test1.uws

WHILE TRUE

t2=GETTIME()

IF G_TIME_HH=13 and G_TIME_NN>=0 and 30>G_TIME_NN BREAK else endif

WEND

call test2.uws

stuncloud commented 5 months ago

問題状況を整理するとcallの関係は以下で間違いないでしょうか

そしてこの場合にmodule.uwsの多重callにより重複定義エラーが発生しているということでしょうか

問題状況でのエラーについての記載がないので推測となりますが、そうだとして以下の対策を考えています

ただし、最初の例にあったような別ファイル上の名前が同じmodule等の定義を重複エラーで弾くのは変わらず仕様とします

すぐに実装できそうなら明日の1.0.0リリースに含めますが、無理であればその先のリリースとなります

Patrick10731 commented 5 months ago

回答ありがとうございます その関係で間違いありません

それとは別にこのようなcall関係も使用しています ・main.uws     ・module.uws   ・test1.uws      ・module.uws

どちらにしてもmodule.uwsについては同一ファイルであること、またmodule.uwsの多重callで多重定義エラーが発生していることに間違いはありません

同一ファイルをcallする場合はmoduleや関数の定義の重複が起こらないようにし、かつ定義以外のスクリプトはいずれの呼び出しからも実行されるようにする

こちらの対策方法で問題なく動くと思われます 実装のほどよろしくお願いします

stuncloud commented 5 months ago

以下に対応しました

constやpublic等の宣言、moduleや関数等の定義は初回call時のみ処理されます

修正は次回リリースに含まれます