コンテンツにスキップ

600 での変更点(Tc600-3以降)

Tc600-3 以降の YAYA(600 系)で、500 系(Tc574-1 まで)から変わった仕様をまとめる。

TL;DR

yaya.dll を置き換えるだけで、500 系の辞書とセーブファイルはそのまま動く。 書き直しは要らない。開発チームの側でも、ほとんどの場合は何も考えずに置き換えている。

気にするのは、次のような場合だけ。

  • 辞書に IHASH HASH_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 の比較と揃えたもの。

キーと要素の両方が 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 系と同じ。

新しいシステム関数と同じ名前

  • IHASH HASH_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 系ではこの複製をしないので、ループで配列を育てる処理が大幅に速くなった。

関連