catch type error in connection.js to partly cope with issue #10
issue #10 への暫定対応として、型エラーを起こす部分を try catch で囲み、型エラーを起こした場合は undo することにしました。これで、明日の授業は乗り切ります。が、以下の問題がわかっています。
- 以下のプログラムで、
xをfの body 部分に入れると(落ちることはなくなりましたが)接続を拒否されたxのブロックがメインワークスペースに残ってしまいます。
let f x = ?
let test = f 0 = true
- 上のプログラムで、
xのブロックを直接、使うのではなく、スコープお砂場を開き、そこからfの body 部分に入れると落ちているようです。
完璧な commit ではないですが、将来、undo がきちんとサポートされた暁には、まあ、使えるコードになりそうなので、pull request しておきます。undo した後、型推論をし直していませんが、する必要があったら加えてください。
ありがとうございます!!今日の授業はこちらを使おうと思います。
型推論が失敗するかどうかのチェックは、connect_ (core.connect.js 内の関数) ではなく、接続できるかどうかをチェックする部分で行ったほうが適切かなと思います。
はい、ぼくもそう思ったのですが、connect_ を見ると、すでに繋がっていたブロックを外すなどいろいろな処理をしているので、単に connectReciprocally_ をするだけで良いのかわからなかったのです。仕方がないので、接続処理が全部終わった connect_ の最後で型を調べ、まずかったら undo という手を考えました。でも、新しいコードを見せられると、確かに接続関係だけを一時的に変更して型推論を行い、あとで戻せば大丈夫そうですね。
そうでないと、接続できることを示す黄色いハイライトが表示されているのに、接続しようとしたら接続できない、と言ったようなへんな状態が起こり得ます。
その部分は全く考えられていません。新しいコードを見て、collect というのがそれを司っているのね、というのを学びました。ありがとうございます。
別のブランチに issue #10 fix案を作成してみました。
変数を let ブロックから直接、動かす方は問題なく動いているように見えます。でも、スコープお砂場を開き、そこから変数ブロックを移動すると、黄色のハイライトになって接続できてしまい、その後、落ちてしまうようです。
あと、mightFixIssue#10 では
- レコードを定義する type 文のブロックを置く。
- フィールドに適当な型を指定する。(指定しなければ下の問題は起きない。)
- type 文の下に let 文を置く。
- type 文の型名をドラッグして let 文の中に置こうとすると https://github.com/harukamm/ocaml-blockly/blob/mightFixIssue%2310/core/connection_db.js#L146 で落ちる。
という問題があるようです。この問題を解決しようと今日一日あちこちのコードとにらめっこしたのですが、解決できませんでした。上の throw している一文をコメントアウトすると落ちなくなるのですが、それは怖そうです。とりあえず、これの解決はあきらめます。
type a_t = {a : int}
let b = {a = ?}
というブロックの ? に対して 0 のブロックを入れようとすると、つーっとブロックが流れます。遡って調べると MightFixIssue#10 の最初のコミット 3744a4fb92d74ba45cd168475b3f108540800cc8 の前では起こらず、このコミットの後から起きる現象のようです。原因に心当たりはありますか。
原因は、blocks/datatypes.jp の create_record_typed の updateStructure の中で `initSvg' を型推論のたびに呼び出していたことのようです。これを「変更があったときのみ」呼び出すようにしたら解決したように見えます。diff は https://github.com/kenichi-asai/ocaml-blockly/commit/273419be45b68a604cb32f9640d49f0d854374bc にあります。