600 での変更点(Tc600-3以降)¶
Tc600-3 以降の YAYA(600 系)で、500 系(Tc574-1 まで)から変わった仕様をまとめる。
TL;DR
yaya.dll を置き換えるだけで、500 系の辞書とセーブファイルはそのまま動く。 書き直しは要らない。開発チームの側でも、ほとんどの場合は何も考えずに置き換えている。
気にするのは、次のような場合だけ。
- 辞書に
IHASHHASH_KEYSなど、新しいシステム関数と同じ名前の関数や変数がある → 関数はConflict.名前に改名され、変数は使えない(詳細) - 配列の要素が VOID 同士の比較や、型の混ざった配列の
ARRAYDEDUPに頼っている → 結果が変わる(詳細) - 600 系で動かしたセーブファイルを 500 系に戻す → ハッシュや入れ子を含む変数が崩れる(詳細)
新機能(ハッシュ、入れ子の配列、JSON / XML / SQLite など)は、使いたくなったときに使えばよい。500 系と共用する辞書は #ifdef で書き分けられる(詳細)。
概要¶
| 項目 | 500 系 | 600 系 |
|---|---|---|
| 値の型 | VOID / 整数 / 実数 / 文字列 / 汎用配列 | + ハッシュ(連想配列) |
GETTYPE / GETTYPEEX |
0〜4 | ハッシュは 5 |
| 配列の要素 | スカラーだけ | 配列やハッシュも要素にできる(入れ子) |
| 要素への代入 | a[x] = v だけ |
a[x][y]... = v(多次元代入)も可 |
| foreach | foreach 式 ; 変数 |
+ foreach 式 ; キー変数, 値変数 |
| セーブファイル | 配列 a:b:c |
+ ハッシュ "k"=v:...、入れ子 IARRAY{...} / IHASH{...} |
| 新しいシステム関数 | ― | IHASH HASH_KEYS HASH_VALUES HASH_SPLIT HASH_EXIST HASH_SIZE、Tc601-1 から FREADJSON FREADXML PARSEJSON PARSEXML、Tc602-1 から FWRITEJSON FWRITEXML DUMPJSON DUMPXML、Tc602-3 から PARSEHEADER、Tc602-5 から FREADYAML FREADTOML PARSEYAML PARSETOML FWRITEYAML FWRITETOML DUMPYAML DUMPTOML、Tc602-11 から SQLOPEN SQLCLOSE SQLEXEC SQLQUERY、Tc605-1 から FREADHTML PARSEHTML |
| 新しい警告 | ― | W0024(ハッシュを - * / % に使った)、Tc601-1 から W0025(ファイルを開けない)・W0026(JSON/XML/YAML/TOML を解析できない)、Tc602-1 から W0027(JSON/XML/YAML/TOML に変換できない)、Tc602-11 から W0029(SQLite の処理に失敗した)、Tc602-13 から W0030(SQL のパラメータより多くの値を渡した)、Tc604-1 から W0031(embed.lazy, off で % の後の名前を確定できなかった) |
文法は ハッシュ と 値の入れ子と多次元代入 を参照。
500 系の a[x][y] = v は読み込み時にエラー E0029 だったので、この構文を含む既存の辞書は無い。
既存の辞書に影響しうる変更¶
配列の要素の VOID 同士の比較¶
配列の要素同士を比べるとき、両方が VOID なら等しいとみなすようになった。スカラー同士の VOID の比較と揃えたもの。
(1, 未定義の変数) == (1, 未定義の変数)が 0 から 1 になるASEARCH(未定義の変数, 配列)が、配列の中の VOID の要素の位置を返すようになる(500 系では -1)HASH_EXIST、ARRAYDEDUP、ハッシュ同士の==でも同じ
キーと要素の両方が VOID のときだけの変更で、整数・実数・文字列の比較は変わらない。
ARRAYDEDUP に型の混ざった配列を渡したとき¶
500 系では、整数・実数・文字列が混ざった配列を渡すと、結果が並び方しだいで変わっていた。600 系では、ハッシュのキーと同じ規則で重複を除き、数値 < 文字列 の順に並べる。
ARRAYDEDUP((10, "9", 9, "a", 1.0, 1, "1"))
// 500 系: 1,1.000000,9,10,9,a
// 600 系: 1.000000,9,10,a
1.0、1、"1" は同じ値とみなされ、最初のもの(1.0)が残る。整数だけ、実数だけ、文字列だけの配列の結果は 500 系と同じ。
setter・watcher に渡る配列¶
FUNCDECL_WRITE(setter)と FUNCDECL_READ(watcher)に渡る値が汎用配列のとき、500 系では値が壊れていた(setter の _argv[1] _argv[2] が空になる、watcher の _argv[1] が先頭要素だけになる、setter の戻り値をそのまま返すと変数が空になる)。
600 系では、配列は _argv の要素として入れ子のまま渡る。_argv の要素数は setter が 3、watcher が 2 のまま変わらない。
500 系で配列の変数に setter や watcher を付けても正しく動いていなかったので、実害はないはず。なお、添字への代入(a[0] = v)で setter が呼ばれないのは 500 系と同じ。
新しいシステム関数と同じ名前¶
IHASHHASH_KEYSなどと同じ名前のユーザー関数は、Conflict.名前に改名され、呼び出しはシステム関数に向く(TOAUTOEX が追加されたときと同じ仕組み)- 同じ名前のグローバル変数は使えない。セーブファイルから復元するときに警告 W0002 が出る
無い要素への複合代入(Tc602-10以降)¶
複合代入(+= -= *= /= %= とコロン付き変種)の左辺が、汎用配列の範囲外の要素やハッシュの無いキーのときは、未定義の変数と同じく VOID として計算するようになった。500 系や Tc602-9 までは空文字列として計算していたので、+= 数値 が文字列の連結になっていた。
_c = IHASH()
_c["a"] += 1
_c["a"] += 1 // 500 系・Tc602-9 まで: "11"(文字列) Tc602-10 以降: 2(整数)
_a = IARRAY
_a[2] += 1 // 500 系・Tc602-9 まで: "1"(文字列) Tc602-10 以降: 1(整数)
- 変わるのは右辺が数値の
+=だけ。-=*=/=%=は空文字列も数値として扱われていたので結果は同じ。+= "文字列"も同じ - 要素があって値が空文字列のとき(
_a[0] = ""のあとの_a[0] += 1)は、これまでどおり"1"になる - 簡易配列(文字列)の範囲外の要素は、もとから VOID として計算していた
- Tc602-10 では、読み出し(
h["none"]や範囲外のa[9])は空文字列を返すままだった。Tc603-1 から読み出しも VOID になった(下記) - 多次元代入では最後の段だけが対象。途中の段が無いとき(空の
_hへの_h["a"]["b"] += 1)は、途中の値ごとの動作 のとおり書き換える。_h["a"]は Tc602-13 までは文字列の"1"、Tc603-1 からは配列の(1)になる ,=は変わらない
無い要素の読み出し(Tc603-1以降)¶
汎用配列の範囲外の要素、ハッシュの無いキー、VOID に [ ] を付けて読むと、未定義の変数と同じく VOID を返すようになった。それまでは空文字列を返していた(簡易配列と数値の範囲外はもとから VOID)。500 系も Tc574-8 から同じ(ハッシュを除く)。詳しくは 範囲外の要素 を参照。
_h = IHASH()
_h["none"] == 0 // Tc602-13 まで: 0 Tc603-1 以降: 1
_h["none"] + 1 // Tc602-13 まで: "1"(文字列) Tc603-1 以降: 1(整数)
GETTYPE(_h["none"]) // Tc602-13 まで: 3 Tc603-1 以降: 0
== "" や if の判定、文字列との連結の結果は変わらない。
配列の中の配列やハッシュへの代入(Tc603-1以降)¶
範囲指定でない代入(_v[0] = x、_v[0] ,= x、_v[0] += x など)で、代入先の要素が配列かハッシュのときは、右辺を展開せずに丸ごと置き換えるようになった。それまでは根が配列だと右辺の配列が展開されて、入れ子が崩れていた(_v[0] = _v[0] でも崩れた)。代入先の要素がスカラーのときの挿入・削除(_a[1] = (8, 9)、_a[1] = IARRAY)は変わらない。詳しくは 内側の配列やハッシュを丸ごと書き換える を参照。
_v = PARSEJSON('[[1,2],[3,4]]')
_v[0] ,= 5 // Tc602-13 まで: 1,2,5,(3,4) Tc603-1 以降: (1,2,5),(3,4)
セーブファイルの互換性¶
- ハッシュや入れ子を含まない変数は、書き出す内容も読み込む結果も 500 系と同じ。500 系のセーブファイルはそのまま読める
- ハッシュや入れ子を含む変数は新しい書式で保存される(SAVEVAR を参照)
- ダウングレードに注意: 600 系で保存したファイルを 500 系で読むと、ハッシュや入れ子を含む変数だけが崩れる(落ちはしない。ほかの変数には影響しない)。崩れたまま保存し直すと、元の内容は失われる
500 系と共用する辞書¶
Tc574-2 以降の 500 系と Tc602-2 以降の 600 系では、#ifdef __AYA_SYSTEM_YAYA6__ や #ifdef __AYA_SYSTEM_SYSFUNC_関数名__ で 600 系向けの部分を書き分けられる。読み込まれない区間は構文を解析しないので、600 系の新しい構文や関数を書いても 500 系でエラーにならない。詳しくは プリプロセス を参照。
性能¶
_a ,= x と _a[i] = x は、500 系では1回ごとに配列を丸ごと複製していた(ループで配列を育てると要素数の2乗に比例して遅くなる)。600 系ではこの複製をしないので、ループで配列を育てる処理が大幅に速くなった。