はじめに
Tera Term のマクロ言語 TTL (Tera Term Language) には、文字列をフォーマットするコマンドが sprintf と sprintf2 の二種類存在します。
同じ用途のコマンドは二つも要らないように思えますが、なぜ sprintf2 コマンドがあるのか、なぜ統一されないのかを解説してみます。
sprintf2 コマンドが生まれた経緯
TTL にはまず sprintf コマンドが追加されました。sprintf はフォーマットされた結果の文字列を inputstr システム変数に格納します。
しかし、この仕様には次のような欠点がありました。
- 変数に関する説明を見ると、"inputstr はホストまたはユーザからの入力を受け取るシステム変数である" という設計思想になっているが、その変数を違う用途に使っている
- sprintf コマンドで文字列をフォーマットすると inputstr システム変数が上書きされてしまうので、受け取っていた文字列が暗黙のうちに削除されてしまう(inputstr 変数について上記のつもりでいると、よりハマりそう)
- 受け取った文字列 inputstr をフォーマットした場合、格納先も inputstr になるので C 言語の memcpy で領域が重複した場合のような不安がある1
そこで、任意のユーザー変数に格納するように sprintf コマンドの実装を修正しようと思いましたが、この欠点に気がついたときにはすでにリリースが行われた後でした。
sprintf コマンドに互換性のない仕様変更を入れてしまうと、すでに sprintf コマンドを利用して書かれたマクロが動作しなくなってしまいます。そのため sprintf コマンドの仕様変更を断念し、sprintf2 コマンドを追加しました。
同じ理由で、sprintf コマンドを削除して sprintf2 コマンドだけにする、ということもできませんでした。
まとめ
sprintf2 コマンドがある理由・sprintf コマンド一つにならない理由は、一言で言えば「後方互換性」です。
行いたかった修正は、以前「プログラマはこんなことも考えている」という記事で書いた「既存の動きと両立しない」修正になるため、「壊さない」かつ「どちらも両立する仕様」にするためにこのような措置をとりました。
大げさな例を挙げると「C 言語の creat 関数が "create" に修正されなかった」「電流の向きは電子の流れる向きと逆のままになった」と似たような理由なのでした。
-
内部では直接 inputstr のメモリ領域に書き出しているのではなく、いったんバッファに入れてからコピーしているので大丈夫なはずです。 ↩