実行時の失敗の出力
値の無い変数、どこにも無い単語、登録していないアクター……書き間違えたまま動かすと、ゴーストは空のまま話を続けてしまいますの。どこで間違えたのか、見ているだけでは分かりにくかったのですわ。
ログを開かなければ気づけない、というのは心細いものでございます。
ですから pasta は、間違えたその場所に、バルーンの中で 【…】 の印を出しますの。この頁で、印の読み方をすべてお教えいたしますわ。
このページは、シーンの実行中に起きる辞書の書き間違い(実行時の失敗)について、バルーンに出る失敗表記とログの警告、表記が出る位置、重ねて出さない規則、表記を出すかどうかの設定、Lua から失敗を報告する方法を示す。Lua のエラーでシーンや要求そのものが止まる場合(止まるエラー)の表記も、止まるエラーの表記で示す。
実行時の失敗では、シーンは止まらずに続く。失敗した後の続き方(値の無い変数や見つからない単語・関数は空として続ける、見つからない Call は飛ばして次の行へ進む、数や文字列にできない被演算子は 0・空文字列として計算する)は、失敗表記を出すかどうかにかかわらず同じである。失敗表記の文字列は、変数への代入・関数の引数・Call の引数・算術・連結の値には混ざらない。
止まるエラーでは、シーンや要求はそこで止まり、続かない。失敗表記の形と切り替えは実行時の失敗と同じものを使い、止まった理由を表記でバルーンに出す(止まるエラーの表記)。起動・読み込み時の失敗はバルーンに出ない。その読み方は 起動シーケンスとモジュール解決 を参照する。
失敗表記の形
失敗表記は、どの種類も同じ形で出る。
【何が起きたか:対象】
【何が起きたか:対象(説明)】
- 何が起きたか は失敗の種類の名前である(次節の表)。
- 対象 は、失敗した参照を辞書の書き方で示す。変数はローカル変数が
$名前、グローバル変数が$*名前、シーン引数が$0・$1…、関数は@名前()・@*名前()・@$名前()、シーンは>名前になる。関数の引数は表記に含まれない(@計算(1)は@計算()と出る)。 - 説明 は値の状態であり、要るときだけ対象の後に
(…)で付く。 - 対象が分からないときは、説明が対象の位置に出る(例:
【数にできない値:"xy"】)。 - 実行時の失敗の表記に辞書の行番号は含まれない。対象の名前と、バルーンの中で表記が出た位置(前後の台詞)が手がかりになる(止まるエラーの表記は、説明のエラー文に止まったファイルと行が入る。止まった場所とエラー文)。
名前や値に、さくらスクリプトのタグとして働く文字が含まれていても、タグとしては実行されず、書いた文字のとおりに表示される。表記の中身では、\ が \\、% が \% に置き換わり、改行(CR・LF)は空白になる。
種類ごとの表記とログの警告
1 件の失敗について、バルーンに失敗表記が 1 つ、ログに警告(warn レベル)が 1 行出る。次の表の辞書の例は、どれもシーンの中の行である。
| 何が起きたか | 辞書の例 | 失敗表記 | ログの警告 |
|---|---|---|---|
| 値の無い変数 | さくら:今日は$話題。の話($話題 に値が無い) | 【値の無い変数:$話題】 | act:talk - undefined variable: 'var.話題' |
| 単語が見つからない | さくら:前@挨拶。後 | 【単語が見つからない:@挨拶】 | proxy:word - handler not found: key='挨拶', mode='word', via=proxy(さくら) |
| 単語が見つからない | $w=@挨拶 | 【単語が見つからない:@挨拶】 | act:word - handler not found: key='挨拶', mode='word', via=act |
| 関数が見つからない | さくら:前@計算(1)後 | 【関数が見つからない:@計算()】 | proxy:expr_fn - handler not found: key='計算', mode='expr', via=proxy(さくら) |
| 関数が見つからない | $f=@計算(1) | 【関数が見つからない:@計算()】 | act:expr_fn - handler not found: key='計算', mode='expr', via=act |
| 関数が見つからない | さくら:前@*計算(1)後 | 【関数が見つからない:@*計算()】 | act:global_fn - function not found: key='計算' |
| 名前にならない値 | さくら:前@$未代入。後($未代入 に値が無い) | 【名前にならない値:$未代入(値なし)】 | proxy:word - undefined variable: 'var.未代入' |
| 名前にならない値 | さくら:@$空()($空 が空文字列) | 【名前にならない値:$空(空文字列)】 | proxy:expr_fn - empty variable: 'var.空' |
| 名前にならない値 | $d=@$真($真 が真偽値) | 【名前にならない値:$真(真偽値)】 | act:word - unsupported value type: 'var.真' (boolean) |
| 名前にならない値 | >$行き先($行き先 に値が無い) | 【名前にならない値:$行き先(値なし)】 | act:call - undefined variable: 'var.行き先' |
| 名前にならない値 | >@真偽()(関数が真偽値を返す) | 【名前にならない値:@真偽()(真偽値)】 | act:call - key is not a string or number: operand='@真偽()', value=true (boolean) |
| 未登録アクター | ぱすたー:こんにちは(ぱすたー が登録されていない) | 【未登録アクター:ぱすたー】 | act:actor_proxy - unregistered actor: name='ぱすたー' |
| 数にできない値 | $y=$x+1($x が 「abc」) | 【数にできない値:$x("abc")】 | act:arith - operand is not a number: op='+', operand='var.x', value='abc' (string) |
| 数にできない値 | $z=「xy」*2 | 【数にできない値:"xy"】 | act:arith - operand is not a number: op='*', value='xy' (string) |
| 文字列にできない値 | $c=$t&「後」($t が真偽値の真) | 【文字列にできない値:$t(true)】 | act:concat - operand is not a string or number: op='&', operand='var.t', value=true (boolean) |
| 文字列にできない値 | $c2=「前」&@真偽() | 【文字列にできない値:@真偽()(true)】 | act:concat - operand is not a string or number: op='&', operand='@真偽()', value=true (boolean) |
| シーンが見つからない | >会話2 | 【シーンが見つからない:>会話2】 | act:call - handler not found: key='会話2', mode='scene', via=act |
| スクリプトのエラー | *会話 の ・雨の日 から呼んだ Lua のブロックの return data.雨(dic\天気.pasta の 5 行目。data が nil。止まった場所とエラー文の例) | 【スクリプトのエラー:*会話・雨の日(dic\天気.pasta:5: attempt to index local 'data' (a nil value))】 | スクリプトのエラー:*会話・雨の日(dic\天気.pasta:5: attempt to index local 'data' (a nil value)) |
| 時間切れ | $幅=$%baseware.version(結果が 5 秒以内に届かない) | 【時間切れ:callback timeout: get_property】 | OnPastaCallBack1: callback timeout: get_property |
各種類の対象になる状況は次のとおりである。
- 値の無い変数: アクション行で、値の無い変数(未代入の変数・値なしを代入した変数・渡されていないシーン引数)を展開した。グローバル変数は
$*名前(警告ではsave.名前)、シーン引数は$0(警告ではargs[1])と出る。 - 単語が見つからない: 単語参照
@単語の単語が見つからない。警告の接頭辞は、アクター付きの行ではproxy:word、それ以外ではact:wordになる。 - 関数が見つからない: 関数呼び出し
@名前(…)の関数、またはグローバル関数の呼び出し@*名前(…)の関数が見つからない。 - 名前にならない値: 動的参照(
@$名前・@$名前(…))または動的コール(>$名前・>@名前(…))の値が、検索に使う名前にならない(値が無い・空文字列・文字列と数値以外)。説明は、値が無ければ値なし、空文字列なら空文字列、真偽値なら真偽値、表なら表、関数なら関数、それ以外は Lua の型の名前になる。警告の接頭辞は参照の場所によりact:word・proxy:word・act:expr_fn・proxy:expr_fn・act:callのいずれかになる。 - 未登録アクター: 登録されていないアクター名のアクション行を実行した。目印は話者がその名前に切り替わるたびに 1 回出る(「重ねて出さない規則」)。
- 数にできない値・文字列にできない値: 算術の被演算子が数にできない値、または連結の被演算子が文字列にできない値だった(値が無い場合を除く)。説明は、文字列なら
"abc"のように引用符付き、真偽値ならtrue・false、それ以外は「名前にならない値」と同じ型の説明になる。 - シーンが見つからない: Call・Jump のターゲットのシーンが見つからない。シーン名の別名(シーン名の別名)で置き換えた名前が見つからないときも、表記には書いた名前が出る。このときログには、上の警告に加えて、書いた名前と置き換え後の名前を含む行(
Scene not found (alias applied))が出る。 - スクリプトのエラー・時間切れ: Lua のエラー、または待ち合わせの時間切れで、シーンや要求が止まった(止まるエラー)。表記の中身と出る応答は 止まるエラーの表記 で示す。
次の場合は失敗として扱わず、表記も警告も出さない。
- 算術・連結の被演算子に値が無い(0・空文字列として計算する)。
- 静的な単語参照の名前が空である。
出る位置
失敗表記は、失敗が起きた時点の出力の位置に出る。
- 発言の途中で失敗したときは、その発言の中の失敗した位置(前の文字の後、後の文字の前)に出る。
さくら:前@挨拶。後は前【単語が見つからない:@挨拶】。後になる。 - アクション行以外の行(変数の代入行・Call 行の引数・式の中・Lua ブロックから呼んだ act のメソッド)で失敗したときも、その時点までに出力した内容の後に出る。
- 失敗表記は、直前に話したアクターのバルーンに続けて出る。失敗表記のためにアクターは切り替わらない。そのため、別のアクターの行の先頭で起きた失敗は、直前の話者のバルーンに出る。
- 出力の先頭(最初の発言より前。チェイントークで再開した直後を含む)で失敗したときは、さくらスクリプトのスコープを切り替えずに出る。
- チェイントーク(チェイントーク)で中断した後、再開してから起きた失敗は、再開した後の出力に出る。
- 未登録アクターの目印だけは例外で、そのアクターの発言の先頭(スコープの切り替えの直後)に出る。
次のシーンを、さくら の立ち位置が 0、うにゅう の立ち位置が 1 で実行した例を示す。@無い単語 は見つからず、$未定義 には値が無い。
*例
さくら:@無い単語、です
うにゅう:$未定義、だね
【単語が見つからない:@無い単語】\p[0]、\_w[450]です【値の無い変数:$未定義】\p[1]、\_w[450]だね\e
1 つ目の表記は出力の先頭なのでスコープを切り替える前に出る。2 つ目の表記は うにゅう の行の先頭で起きたが、直前の話者 さくら のバルーンに続けて出る。
登録されていない ぱすたー の行(立ち位置は 0 になる)の先頭で単語が見つからない場合は、目印の後に表記が出る。
*例
ぱすたー:@無い単語、だよ
\p[0]【未登録アクター:ぱすたー】【単語が見つからない:@無い単語】、\_w[450]だよ\e
失敗表記には、台詞と違って句読点のウェイトも自動の改行も入らない。失敗表記を挟んでも、前後の台詞のウェイト・自動の改行・段落区切りの改行・アクターの切り替えは、失敗が無い場合と同じに出る。ただし、別のアクターからスコープを戻った直後の発言が失敗表記で始まる場合は、段落区切りの改行が失敗の無い場合と変わることがある。
重ねて出さない規則
1 つの原因に対して、失敗表記は 1 つ、ログの警告は 1 行だけ出る。内側の参照が失敗を報告したとき、その結果の値の無さを受け取った外側は、失敗を重ねて報告しない。
| 内側(報告する) | 外側(報告しない) | 例 |
|---|---|---|
| 単語・関数・グローバル関数が見つからない | アクション行の展開 | さくら:@挨拶 は 【単語が見つからない:@挨拶】 だけ |
| 動的参照の値が名前にならない | 単語・関数の検索 | さくら:@$未代入 は 【名前にならない値:$未代入(値なし)】 だけ |
| 動的コールの変数の値が名前にならない | Call の検索 | >$行き先 は 【名前にならない値:$行き先(値なし)】 だけ |
| 動的コールの関数が見つからない | 動的コールの値の判定 | >@無い関数() は 【関数が見つからない:@無い関数()】 だけ |
| 被演算子の関数が見つからない | 算術・連結 | $a=@無い関数()+1 は 【関数が見つからない:@無い関数()】 だけ |
| 未登録アクター | 立ち位置の警告 | ログに actor_spots fallback の行は出ない |
- 未登録アクターの行(継続行を含む)が続くときは、目印と警告は話者がその名前に切り替わったときに 1 回だけ出る。間に別のアクターの行を挟んで戻ると、もう一度出る。
- 同じ書き間違いが別の行・別の回で起きたときは、それぞれの回で報告する。一度報告した名前を以後は黙る、という抑止はしない。
- 値なしを代入した変数を後で展開した場合は、代入の行と展開の行で別々に報告する。
$x=@挨拶の後のさくら:$xは、【単語が見つからない:@挨拶】と【値の無い変数:$x】の 2 つになる。
表記だけの出力
シーンの出力が失敗表記だけになったときも、空の出力としては扱わず、失敗表記を含む出力を返す。たとえば登録されていない ぱすたー の ぱすたー:$未定義 だけのシーンは、【未登録アクター:ぱすたー】【値の無い変数:$未定義】 を含む出力になる。
失敗表記を出さない設定(次節)では、表記だけだった出力は何も出さないシーンと同じ扱い(SHIORI の 204 応答)になる。
表記の切り替え
pasta.toml の [logging] の balloon_warning(真偽値)で、失敗表記をバルーンに出すかどうかを切り替える。キーの一覧は [logging](ログ出力) を参照する。
[logging]
balloon_warning = false
- 書かなければ
true(失敗表記を出す)である。 falseのときは、未登録アクターの目印とシーンが見つからない場合の表記を含め、すべての失敗表記を出さない。バルーンの出力は、trueのときの出力から失敗表記を除いたものと同じになる。- 止まるエラーの表記(止まるエラーの表記)も、この設定で切り替わる。
falseのときの止まるエラーの応答は、これまでと同じ(500 とX-Error-Reason。出る応答)になる。 - ログの警告は、この設定にかかわらず出る。ログに記録するかどうかは、これまでどおり
level・filterが決める。level = "error"で警告がログに残らない設定でも、失敗表記はballoon_warningだけで決まる。 - 値が真偽値でないときは、書かなかった場合と同じ
trueになる。[logging]の他のキー(file_path・level・filter)はこの値の影響を受けない。 pasta_check(releaseを含む)の動作は、この設定によって変わらない。
既定の true のままでは、配ったゴーストでも、利用者のバルーンに失敗表記と止まるエラーの表記が出る。ゴーストを配る前に balloon_warning = false を書く。既定値は変わらず、pasta_check release もこの行を書き足さない。
止まるエラーの表記
GET の要求の処理中に Lua のエラーが起きて、その要求の処理が続けられなくなったとき(止まるエラー)も、その要求の応答で、止まった理由を失敗表記としてバルーンに出す。次の場所で起きたエラーが対象で、どこで起きても表記の形は同じである。
- イベントのハンドラ(
REGに登録した関数・既定のハンドラ) - イベントで始めたシーン、チェイントークで再開したシーン
- プロパティの待ち合わせ(
act:get_property)から再開したシーン - 待ち合わせの時間切れ(時間切れ)
止まったシーンは再開されず、チェイントークの続きと待ち合わせは捨てられる。表記を出した後の要求は、エラーが無かったときと同じに処理される。
2 つの種類
| 何が起きたか | 失敗表記 | 出るとき |
|---|---|---|
| スクリプトのエラー | 【スクリプトのエラー:止まった場所(エラー文)】 | Lua のエラーで止まった |
| スクリプトのエラー | 【スクリプトのエラー】 | エラーの値が文字列でない(error({}) など) |
| 時間切れ | 【時間切れ:理由】 | act:get_property の待ち合わせが時間切れになった。理由は timeout_message(既定は callback timeout: get_property) |
形と、さくらスクリプトのタグとして働く文字の扱いは、実行時の失敗と同じである(失敗表記の形)。エラー文の中の \(Windows のパスの区切り)や % も、書いた文字のとおりに表示される。1 件の止まるエラーにつき、表記は 1 つ出る。
止まった場所とエラー文
止まった場所(表記の対象)は次のように示す。
- シーンの中で止まったときは、そのシーンを辞書に書いた名前で示す。グローバルシーンは
*名前、ローカルシーンの中なら*グローバルシーン名・ローカルシーン名になる。シーンから呼んだ Lua のブロックの関数やscripts/の関数の中で止まったときも、呼んだシーンの名前になる。 - 別名(シーン名の別名)で登録したシーンも、書いた名前で出る。
*会話はOnTalkではなく*会話と出る。 - 同じ名前のシーンが複数あるときは、書いた名前だけを示し、どの 1 つかは区別しない。区別したいときは、シーンに別の名前を付ける(ランダムトークのまま分けるなら、
*OnTalk_新しいおもちゃのように書く)。 - シーンの外(
REGに登録したハンドラ・既定のハンドラ)で止まったときは、要求のイベントの ID(OnBootなど)で示す。
エラー文(表記の説明)は、Lua のエラー文の最初の行である。2 行目以降とスタックトレースは出さない。エラー文の先頭の場所は、次のように直して出す。ファイルは、ゴーストのフォルダーから見た形になる。
| 止まった所 | 表記に出る場所 |
|---|---|
| 辞書の中(アクション行・Lua のブロック) | .pasta のファイルと行(dic\天気.pasta:5:) |
ゴーストのフォルダーの中の、作者が置いた .lua(scripts/ など) | そのファイルと行(scripts\天気.lua:6:) |
辞書から変換した Lua・pasta の標準ランタイム(pasta_scripts/)・pasta の内部でエラーを投げ直した場所 | 出さない |
辞書の中で止まっても、.pasta の行に直せないとき(別のグローバルシーンや別のファイルの Lua のブロックの関数を呼んで、その中で止まったときなど)は、場所を出さずにエラー文だけを出す。error("…", 0) のように場所の付かないエラー文は、そのまま出る。
次の辞書 dic/天気.pasta を、ランダムトーク(*会話)として実行した例を示す。
*会話
```lua
function SCENE.雨を調べる(act)
local data = nil
return data.雨
end
```
>雨の日
・雨の日
さくら:雨の日は……
さくら:@雨を調べる()
5 行目の return data.雨 で止まり、バルーンには途中までの台詞の後に次の表記が出る。
【スクリプトのエラー:*会話・雨の日(dic\天気.pasta:5: attempt to index local 'data' (a nil value))】
Lua のブロックの代わりに、scripts/天気.lua の関数を呼んで、その 6 行目で止まったときは、scripts\天気.lua:6: が出る。
【スクリプトのエラー:*会話・雨の日(scripts\天気.lua:6: attempt to index local 'forecast' (a nil value))】
scripts/main.lua で REG.OnBoot に登録したハンドラが、7 行目の error("設定が読めない") で止まったときは、イベントの ID が出る。
【スクリプトのエラー:OnBoot(scripts\main.lua:7: 設定が読めない)】
途中の台詞
シーンやハンドラが、エラーが起きるまでに積んだ台詞は捨てずに出し、その後に表記を出す。表記の前に出た台詞が、辞書のどこまで進んで止まったかの手がかりになる。表記を出さない設定では、途中の台詞もこれまでどおり出ない。表記は、実行時の失敗と同じく、直前に話したアクターのバルーンに続けて出る。
出る応答
| 設定 | ステータス | 応答の値(Value) | 応答の理由の行(X-Error-Reason) |
|---|---|---|---|
表記を出す(balloon_warning = true・書かない) | 200 OK | 途中の台詞と表記 | 表記を出さないときと同じ |
表記を出さない(balloon_warning = false) | 500 Internal Server Error | 無し | これまでと同じ(エラー文の最初の行) |
- 表記を出すときのステータスが 200 なのは、SSP が 500 の応答の値をバルーンに出さないためである(SSP 2.9.18 で確かめた)。失敗の応答であることは、
X-Error-Reasonの行で示す。 - 応答の理由の行の中身は、表記を出すかどうかで変わらない。表記と違い、場所は直さずに Lua のエラー文の最初の行のまま入る。
次の場合は、設定にかかわらず表記を出さず、これまでと同じ応答になる。
- ID が
Onで始まらない GET の要求(version・name・menu.…などのリソースの要求)で止まった。応答の値が台詞として表示されないため、500 とX-Error-Reasonを返す。 - 通知(NOTIFY)の要求で止まった。何も表示しない。
- 作者が
RES.err(理由)で作った応答を返した。Lua のエラーではないので止まるエラーにならず、その応答がそのまま返る(RES)。 - ゴーストの読み込みに失敗しているなど、要求が Lua の処理に届く前に 500 になった(ゴーストが起動しない・喋らないとき)。
時間切れ
act:get_property の待ち合わせが時間切れになると、待っていたシーンは timeout_message を理由とするエラーで止まる(OnPastaCallBack)。
- 表記を出す設定では、その回の OnSecondChange の応答で
【時間切れ:callback timeout: get_property】(timeout_messageを渡したときはその文字列)を出す。X-Error-Reasonはtimeout_messageの文字列そのものである。 timeout_messageに文字列でない値(falseなど。省いたときは既定の文字列になる)を渡した待ち合わせは、時間切れでもエラーにならず、そのままシーンを再開する。再開したシーンがエラーで止まったときは、その回の OnSecondChange の応答で【スクリプトのエラー:…】を出す。表記を出さない設定では、これまでどおり応答を作らない。- 時間切れが応答を生んだ回は、その回の OnTalk・OnHour は発行されず、次の回以降に回る。
- 1 回の OnSecondChange で複数の待ち合わせが時間切れになったときは、これまでどおり最初の応答だけを使う。表記を持つ応答も同じに扱う。
ログの警告
止まるエラー 1 件につき、ログに警告(warn レベル)が 1 行出る。表記を出す設定かどうか、ID が On で始まるかどうか、GET か NOTIFY かにかかわらず出る。中身は表記と同じもの(種類・止まった場所・直したエラー文)から、【 】 の枠を除いたものである。タグとして働く文字の置き換えはせず、辞書から変換した Lua の場所も出ない。
スクリプトのエラー:*会話・雨の日(dic\天気.pasta:5: attempt to index local 'data' (a nil value))
timeout_messageを持つ時間切れでは、再開の前に出る警告(OnPastaCallBack1: callback timeout: get_propertyのように、待ち合わせのイベント名と理由)がその 1 行になる。timeout_messageの無い時間切れで再開したシーンが止まったときは、待ち合わせのイベント名を前に付けて出る(OnPastaCallBack1: スクリプトのエラー:…)。
繰り返すエラー
同じ書き間違いによるエラーが、別の要求で繰り返し起きたときは、それぞれの回で表記を出す。一度出したエラーを以後は黙る、という抑止はしない。たとえば OnSecondChange のハンドラで止まり続けると、毎秒の応答に表記が出る。直せば消え、balloon_warning = false でも消せる。
Lua から失敗を報告する
act:failure
Lua のコード(シーン内の Lua ブロック・scripts/ のスクリプト)からは、実行中の act の failure(text, warning) で、辞書の失敗と同じ出口から失敗を報告できる(failure(text, warning))。
function SCENE.直接失敗(act)
act:failure("Lua失敗:テスト", "test - direct failure")
end
textは失敗表記の中身である。【】はこの関数が付けるので、上の例は【Lua失敗:テスト】になる。textも他の失敗表記と同じく置き換えられ、タグとして働く文字は文字のとおりに表示される。warningを渡すと、その文字列がログに警告(warn レベル)として 1 行出る。nilならログには出さない。- 表記は、呼んだ時点の出力の位置に出て、
[logging] balloon_warningの設定に従う。
実行中の act の制限
PASTA.num・PASTA.str(PASTA.num(op, v, desc))は act を引数に取らないため、失敗表記を実行中の act に積む。実行中の act は、同じコルーチン(スレッド)で最後にシーンを始めた(init_scene を呼んだ)act である。辞書から生成したコードでは、チェイントークで再開した後を含めて、これは常にそのシーンの act になる。
Lua から直接呼ぶ場合は、次の制限がある。
- 同じコルーチンの中で、Lua のコードが別の act でシーン関数を呼ぶと、その関数から戻った後も、実行中の act は内側の act のままになる。その後に
PASTA.num・PASTA.strで起きた失敗の表記は、内側の act に積まれる。 - シーンを始めていないコルーチンの中で呼ぶと、ログの警告だけが出て、失敗表記は出ない。
- コルーチンの外(メインスレッド)で呼ぶと、失敗表記は、そこで最後に
init_sceneを呼んだ act に積まれる。この対応は、次にinit_sceneを呼ぶと上書きされる。 - Lua から
act:callを値の無いキーで呼ぶと、【名前にならない値:値なし】が出て、ログにact:call - nil key (undefined variable?), skipping scene searchが出る。 WORD.dynamic_keyを act を渡さずに呼んだときは、ログの警告だけが出て、失敗表記は出ない(WORD.dynamic_key(value, var_path, via, act))。
【…】 が出たら、慌てずにこの頁の表と見比べなさいまし。何をどこで間違えたのか、すぐに見当がつきますわ。
配る前には balloon_warning のこともお忘れなく。利用者の方の画面に、開発の跡を残さずに済みます。