読者です 読者をやめる 読者になる 読者になる

shareテーブルの改善

NYAGOS は各処理で別々の Lua インスタンスを作成して利用しており、~\.nyagos で定義したグローバル変数nyagosテーブル 、shareテーブルに代入されたもの以外は各処理から参照することができません。したがって、データ共有にはユーザ向けテーブルである share を通常用いるのですが、

share.git = {}
share.git.subcommand=gitsubcommands
share.git.branch = branchdetect

という使い方が出来ないという問題がありました()。これは

  • shareテーブルの各要素の実体は Go 側にある
  • shareテーブルへの代入をトリガー(__newindex)に値が、原本の方へ反映される
  • share.git.branch への代入ではトリガーが起動せず、原本の方への反映ができない

といった理由があったためです。そのため

share.git = {
    ["subcommand"]=gitsubcommands,
    ["branch"] = branchdetect,
}

あるいは

local gittmp = share.git
gittmp.subcommand=gitsubcommands
gittmp.git.branch = branchdetect
share.git =gittmp

という書き方をしなければいけませんでした。

で、今回その問題を部分的に解消しました。

具体的には、share.XXX を取り出す際にテーブルだった際、XXXLua側の複製テーブルにもトリガーを設定して、share.XXX.YYY=ZZZという代入もキャッチするようにしました。これを実現するために XXX のメタテーブルには下記の値がセットされています。

  • ["__newindex"]= 更新をキャッチする関数
  • [".."]= 自分の親となる share[] のキー文字列
  • ["age"]= share[] へ直接代入された時の回数(これが最新でなかったら share[] には別の値が既に代入されている)

ただ、この方式だと share.WWW.XXX.YYY = ZZZ という、さらに深い階層での代入までキャッチできません。 次のようなことを考えると、あまり完璧実装しても益が少ないだろうと思っての手抜き実装であるためです。

  • ここまで深い階層を一度に取り扱うのは逆に書きづらいからユーザもやらないだろう
  • 将来的に他の組込言語をサポートし、Lua 依存性を下げるため、ここであまり完璧なものを仕上げても意味がないかもしれない

あと、Luaインスタンスですが、マルチスレッド環境で用いるとパニックの原因となるため、極力細かく別のインスタンスを用意していました。 が、分離しなくてもいいところまで分離していたところがありますので、これも可能な範囲で統合して、share テーブルを意識しないでよい方向へ持っていきたいと考えています。

今のところ、別インスタンスになっていたプロンプト関数(nyagos.prompt)を、.nyagos読み取りのインスタンスと同じにしました。 あと一行入力内・補完も本来は同じインスタンスでいけるはずなので、現在、調査・検討中です。

しかし、面倒くさい話です。Lua インスタンスがクローンできたら、こんな苦労はないのですが。もっと言えば、UNIXだったらプロセスごとクローンできるのですが。 やはり、C言語ではなく、Go言語で作成された組み込み言語を使いたいものです。

いや、自分の設計が悪いのをツールの責任にしてはいけませんね。