SSブログ

クロージャの完全対応等(v2.0.23.0) [資産管理電卓(LineCalc)]

資産管理電卓 v2.0.23.0 で以下の機能対応バグフィックスを行いました。

・クロージャの完全な対応。
・リソースの複数バインド対応。
・callcnt,unbindres の削除、cmp,cmpval,cmpstr の追加
・最後に0が入る数値の比較不具合修正
・比較演算子の文字列演算指定 & に対応
・grph コマンドで負数のインデックスに対応
・grph コマンドでインデックスの数値、文字判定を厳密化
・grph コマンドで1つでも文字インデックスがあれば全て文字インデックスとみなす対応
・無名関数を含む配列のコピー対応
・関数配列帰り値()無指定呼び出し対応
・配列変数の帰り値無名関数対応
・関数代入でのthisを元コンテキストに固定
・setcomで変数配列が両方あった場合同時設定対応
・cpdim,mgdim無名関数対応
・isbind閉じカッコ抜け対応
・無名関数を含む配列 = 代入でのデフォルトthisコピー参照対応
・バインド変数代入でバインド対応
・context,stringbuffer,jxon,xml,cpycnt 代入だけでバインド対応
・prc 作成直後に削除すると中断されない不具合修正
・dbgでコンテキストリソースの内容が表示されない不具合修正
・F1補完でコンテキストリソースの内容が出ない不具合修正
・F1補完で非定義変数のコンテキストドット補完をすると落ちる不具合修正
・コンテキスト配列とローカル配列代入エラーデグレード修正

今回コンテキスト(変数領域)とリソース管理にガベージコレクタが導入されました。
それに伴いcallcnt,unbindres が削除され bindres の動作が変更になっています。
互換性に問題が出るためメジャーバージョンを上げました。

・クロージャの完全な対応
今までも簡易的なクロージャに対応していました。
{
 fnc(dosome,
  {
   prc("{delay(1000)/*do something*/,@1}",#@1)
  }
 ),
 tmp = 123,
 v = dosome(=>{lprint(tmp)}),
 v2 = dosome(=>{lprint(tmp * 2)}),
 waitres(v,v2)
}

上記のように非同期実行後コールバックを行う dosome 関数の定義で、無名関数を使ってコールバックを引数で渡す場合、 v,v2 に PRC リソースの ID を得て待つ必要がありました。
そうしないと、dosome を呼び出した関数終了時に tmp 変数が消去されてしまい並列処理が終わった段階で呼び出しても変数にアクセスできませんでした。
また、dosome 内の prc にコールバック関数(@1)を渡す際には prc の引数にしないと dosome 関数を出た時に dosome 内で定義された変数が消去されるためにアクセスできませんでした。
無名関数で外部変数をアクセスし非同期処理や関数を返す場合、変数生存管理が必要でコードが煩雑になり不便でした。

今回完全にクロージャに対応したので以下のように記載できるようになりました。
{
 fnc(dosome,
  {
   fn = #@1,
   prc(=>{delay(1000)/*do something*/,fn})
  }
 ),
 tmp = 123,
 dosome(=>{lprint(tmp)}),
 dosome(=>{lprint(tmp * 2)}),
}

変数への参照がある限り参照された変数が定義されているコンテキスト(変数定義領域)は残り続けるようになり、関数が終了しても参照されている変数が残り続けますので、変数がいつ消えるか考えながらプログラムする必要が無くなり、コードが簡潔に記載できるようになりました。

参照されているコンテキストが保持されるため以下のような記載も可能です。
{
 fnc(tes,{ tmp = 0,=>{tmp = tmp + 1} }),
 fn = tes,
 lprint(fn()),
 lprint(fn())
}

上記は 12 と表示されます。
関数 tes の中の変数 tmp は tes 内の無名関数により拘束され tes から返される無名関数を保存している変数がある限り保持され 1 , 2 と前回の値に 1 が足されていきます。

・リソースの複数バインド対応
リソースに bindres で複数の変数にバインドできるようになりました。
リソースは作成するとグローバルに作成されるので消すには管理が必要です。
{
 ctx = context,
 ctx.foo = 123,
 lprint(ctx.foo),
 delres(ctx)
}

これだと消し忘れも多いため、bindres で変数にバインドすると変数消去とともにリソースも消去されます。
{
 bindres(ctx,context),
 ctx.foo = 123,
 lprint(ctx.foo),
}

今まではリソースは1変数にしかバインドできませんでしたが、複数の変数にバインドできるようになりました。
{
 bindres(ctx, context), 
 ctx.yaa = 123, 
 fnc(tes, { bindres(ctx2, @1), lprint(ctx2.yaa) }), 
 tes(ctx)
}

上記では関数 tes に渡したコンテキストリソースIDを tes 内でさらにバインドしています。
tes が終了した時点で tes の ctx2変数は消去されバインドは解除されますが、もう一つバインドされているためリソースは削除されず変数 ctx が削除された後に削除されます。

{
 bindres(ctx, context), 
 ctx.yaa = 123, 
 fnc(tes, { bindres(ctx2, @1), prc(=>{delay(1000), lprint(ctx2.yaa)})}), 
 tes(ctx)
}

上記では関数 tes 内で ctx2 にリソースがバインドされ prc 内の無名関数 =>{} に関数 tes の変数が拘束されます。prc 内で ctx2 を使用後 ctx2 が削除されリソースが削除されます。

bindres はリソース1つに対して行われコンテキストリソース内のコンテキストリソースによるツリー構造に対応するには、参照先コンテキストリソースをバインドでコンテキストリソース内変数に保持しておく必要があります。

{
 bindres(ctx, context), 
 bindres(ctx.ctx2, context), 
 bindres(ctx.ctx2.ctx3, ctx) 
}

上記のような自己参照を含むループ構造もガベージコレクタにより削除されます。

バインドした変数を他の変数に代入すると代入先の変数もバインドされます。
{
 bindres(ctx,context),
 ctx2 = ctx // ctx2 は ctx のリソースにバインドされる
}


関数の帰り値としてバインドしたコンテキスト変数を返すと、呼び出し元では帰ってきたリソースの破棄は必要なくなります。

{
 fnc(tes, {bindres(ctx, context), ctx.foo = 123, ctx}),  // ctx はバインドされ帰り値として返される
 ctx2 = tes,  // ctx2 は帰り値のリソースにバインドされるのでリソース破棄必要なし
 lprint(ctx2.foo),
 lprint(tes.foo) // これでもOK
}


bindres で一度変数にバインドしておけば参照がなくなればガベージコレクタにより破棄されるためリソース破棄管理は必要なくなります。

context,stringbuffer は代入だけでもバインドされるようにしました。
bindres を書かなくても変数に代入しておけばリソース管理は必要なくなりました。
web,grph は関数終了後も表示を続けたい場合があるので明示的なバインドでの管理を必要としています。
prc は実行が終われば削除されます。

{
 ctx = context, // 代入だけでバインドされる
 ctx.foo = 123,
 lprint(ctx.foo)
}


delres はリソースを強制的に削除します。
リソース内でバインドされた変数は変数削除と同じ動作が行われます。

callcnt , unbindres は廃止されました。

・cmp,cmpval,cmpstr 追加
演算子 >,<,>=,>=,==,!= は文字列か数値かを自動判定します。
"105.5a" == 105.5 は 1 が返ります。
そうではなく、自動判定、数値、文字列を選択して比較する関数 cmp,cmpval,cmpstr を作成しました。

・最後に0が入る数値の比較不具合修正
"150.50" == 150.5 は "150.50" が文字列と誤判断されていて 0 が返っていました。
最後に0が入っても数値と判定するようにしました。
数値の最後に文字列が入っても数値と判定されます。
"150.50a" == 150.5 は1が返ります。

・比較演算子の文字列演算指定 &
比較演算子の後ろに "&"をつけると文字列比較になるようにしました。
"150.50a" ==& 150.5 は0が返ります。
"150.50a" == 150.5 は1が返ります。

・grph コマンドで負数のインデックスに対応
{
 tmp = [0::1, -24::3],
 grph(tmp)
}

上記のような負数のインデックスのグラフのインデックスのソートが正常に行われず -24 が文字列ラベルと判定されていたのを修正しました。

・grph コマンドでインデックスの数値、文字判定を厳密化しました。
・grph コマンドで1つでも文字インデックスがあれば全て文字インデックスとしました。
grph コマンドで数値、文字判定をLCSの計算と同一にしました。数値の後に文字列が続いても数値と判定されます。
今までインデックスは数値、文字が混在するとグラフが崩れていましたが1つでも文字があると全て文字とするようにしてグラフが崩れないようにしました。

・無名関数を含む配列のコピー対応
配列に無名関数が含まれていた場合コピーすると参照が反映されていなかったのを修正しました。
{
 foo = 123, 
 tmp = [=>{lprint(foo)}], 
 tmp2 = tmp, 
 tmp2[0]
}


・関数配列帰り値()無指定呼び出し対応
関数で帰り値に無名関数の配列が返った場合 () を指定しなくても呼び出すようにしました。
{
 foo = 123, 
 tes = =>{ [=>{lprint(foo)}] }, 
 tes()[0] // 最後に() 必要なし
}


コメント(0) 
共通テーマ:パソコン・インターネット

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

※ブログオーナーが承認したコメントのみ表示されます。

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。