標準愚痴出力

個人的なIT作業ログです。もしかしたら一般的に参考になることが書いているかもしれません(弱気

スーパーで…

(twitterから転載)

スーパーで、本来は専用の容器を買わないと取ってはいけない氷を、ポリ袋に取り込んでいるじいさんがいた。 やらしいなぁと蔑むような目で見てしまったのだが、 よく考えればじいさんも好きでそんな卑しいことはしたくはないだろう。 豊かであれば、わずかなお金をけちる真似したくはなかっただろう。

知識人が日本が貧しくなることを肯定するようなことをいっているようだが、 こういう実態をわかっているのだろうか。 豊かであればこそ、守れるマナーも、ルールも、誇りもある。 貧しくなければ、ジャン・バルジャンも銀の食器を盗まなかっただろう。

自分は比較的マナーの類いは守るようにしている(と思う、たぶん、きっと)。 それは親が不自由なく育ててくれて、ちゃんと学校に行かせてくれて、 学をつけてひとりでそれなりに食べていけるようお金をかけてくれたからだ。 貧しくなると、そういうことが難しくなってしまう

国が貧しくなるというのは、国民の気品を保つことがまず「しんどく」なることを、 左翼系知識人は自覚して欲しいものだ。終わり

Visual Studio 2017 の環境の source の仕方

Developper Command Prompt for VS2017 のプロパティーを見るとリンク先は次のとおりとなっています。

%comspec% /k "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\VsDevCmd.bat"

ちなみに作業フォルダーは "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\"

これを nyagos で読み込む場合は ~\.nyagos

nyagos.exec{'source',[[C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\VsDevCmd.bat]]}

と書きましょう。最新版なら ~\_nyagos

source "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\VsDevCmd.bat"

と書いても Ok です。うまくいかない場合は source の後に-v(画面に読み込み結果やテンポラリファイルの内容を表示する) や-d(テンポラリファイルを消さない)などをつけてみてください(で、ご相談ください)

To Do

Qiitaについて思うところのポエム

Qiitaの新しいガイドラインに対する反発が増えている。自分もどうかと思うところがあった。

新しいガイドラインだと、わたしがNYAGOSでやってるような 「アプリ開発者自身による機能紹介」が「宣伝行為」と解釈可能で、グレーゾーンになるOSSならばよいという話でもないだろう。 一応「自社の宣伝」とあるが、法人と個人を分ける合理的理由が思いつかない。 営利団体ではなく、非営利団体ならよいのか? OSS という無償で配布される成果物に営利か非営利かを分けるラインはあるのか?

「空気読め」という意見もあるが、それで済ますのはよくない。 「忖度」を強いるのは、意思決定に携わる人間の責任をうやむやにする悪しき慣習である

ならばどうすればよいかというと、自分が思うに、 記事の品質の向上はユーザの良識に訴えるのではなく、システムで担保すべきところだろう。 具体的には twitter のような「ミュート」や「ブロック」機能を実装すべきだ。 ブロックなどの否定的な投票が一定数を超えたら、自動でその記事は凍結でよいではないか。

Qiita については、しばらくは投稿を見合わせ、様子見が必要だろう。 なにせ、自分もグレーゾーンに入っているんで。 ただ、よい発表の場なので、失われるのは惜しい。 マークダウンのプレビュースピード速いし。

余談だが「無駄に検索ヒット率が高くなっている」 「質の問題をシステムで担保するのではなくユーザの良識に無駄に訴えた」という点で、 「はてな(ブックマーク)」と「Qiita」は似ている。 ガイドライン作成に逃げたのは、その費用はそれほどかからないというのがあるだろう。 ミュートやブロックなどの開発は結構大がかりでたいへんだというのは想像がつく。

次は nyagos 4.2 になりそう

先日考えた Lua インスタンスをクローンする方式は、 集中してやったら、案外あっさり出来た。

foo = {
    {
        { "bar" }
    }
}

nyagos.alias.foo = function(this)
    print("foo=",foo[1][1][1])
end

こういうコードは、従来の 4.1 では foo=nil となってしまっていたのだが、最新版では foo=bar と出せるようになった。

なぜ 4.1 で期待どおり動かないかは説明しづらく、NYAGOS にとって負い目のような仕様だった。 今回の修正では ~/.nyagos で定義した shareテーブル以外のグローバル変数も、 エイリアス関数・プロンプト関数・一行入力のキー関数のいずれでも参照できるようになった。 これでほとんどの Lua ユーザが戸惑うことはなくなるだろう。

また、今まで無駄に新規 Lua インスタンスを作成していた箇所があり、それでNYAGOSの起動そのものが遅くなっていた。 今回、あくまで新規の goroutine を作った時、すなわち「foo | more」「foo &」などのように、 エイリアスをバックグラウンドで実行させたときだけ Lua インスタンスの作成・クローンを行うようにした。 このコスト削減で、Lua のクローンのコストも相殺されたのではないかと思われる。

ただ、従来の share は廃止しない。というのも、Lua インスタンスのクローンでは、 親(フォアグラウンドgoroutine)→子(バックグランドgoroutine)へと情報が伝わるだけで、 子 → 親へは伝わらないからだ。 使う機会はゼロではないが、念のため、残しておくのが無難だろう。

という感じで、かなり大胆にコードを書き替えた。 それで、安定度は下がったものの、4.1.x の負い目は払拭した。ゆえに次回は 4.2.0 か 4.2-beta というリリースになる予定だ

わたしにいい考えがある

Lua に clone 機能があればと書いていたが、実際に clone を自前で書いてしまった方が早いのでは?

  • local 変数はクロージャーの上位値の clone ができない
    • それは仕方がないと考える
  • clone した後、clone先からclone元へのフィードバックができない
    • 従来の share テーブルも併用する
    • 表向きは share を使ってくださいで、実はその他の変数も clone する
  • io やら os やらのテーブルの複写はどうするか
    • new → openlib → 自前clone の順で実行する
    • コピー先の既にオブジェクトがある場合はスキップするようにする

などなど

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言語で作成された組み込み言語を使いたいものです。

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

Goで、そのうち使ってみたいライブラリ・ツールリスト