何が起きたのか
TOML規格レポジトリにこの記事のタイトルの通りのアップデートがあった。
基本的に、toml11ではTOMLのmasterブランチに入った変更は TOML11_USE_UNRELEASED_FEATURES
を define
しないと有効にならないようにしている。だがこの手の"Clarification"の類は、もしtoml11がそれに則らない振る舞いをする場合、まだTOML側でリリースされていなくてもtoml11側の修正案件としている。これは「以前からこの振る舞いを想定していたが、これまで陽に書かれていなかっただけ」という解釈による。実際のところは最初から全てのエッジケースを想定していたと言うことはないだろうが。
このアップデートでは、以下のようなケースでの振る舞いが明確化された。
str = """"This," she said, "is just a pointless statement."""" # 文字列の内容は"This," she said, "is just a pointless statement." # になる(最初と最後の`"`は文字列の内容に含まれる)
何が問題だったのか
TOMLでは"""
や'''
で始めた文字列はmultiline stringになる。そしてその場合は、"
が文字列中に(エスケープなしで)現れることが許される。
ではこの場合、"""
の直前や直後に"
が来たらどうなるだろうか? 外側の"""
をとるか内側の"""
を取るかで、そのような文字列が文法的に正しいかが決まる。
以下に示すのは、文字列の最初と最後に"
が来て欲しい比較的ありそうなケースだ。よく見ると、最初の"""
が3つではなく4つになっている。
str = """"This," she said, "is just a pointless statement.""""
この場合のこの文字列の内容は "This," she said, "is just a pointless statement."
が正しく、もっとも外側の """
デリミタが正しいデリミタの位置である。
このことが今までのspecだと曖昧だった。
toml11側の対応
これに今日気づいて、閉じる方の"""
は最短マッチしてしまうと言うtoml11側の"不具合"を直した。"不具合"を"で括っているのは、v0.5.0時点の規格を厳密に参照するならここの動作は"処理系定義"に近いと感じているからだ。実際ClarificationはまだTOML仕様としてリリースされていないので。
あと、これに関する挙動を調べている時に、文字列のシリアライズ時にmultiline stringになるかどうかの場合分けとその場合のフォーマットがあまり美しくないなと感じたので、そこもあとで直す。
例えば、'
で括られたliteral stringは一切のエスケープシーケンスを持たないので、literal stringの中で'
を使おうとすると'''
を使ってmultiline literal stringにするしかない。そこは正しく処理できるのだが、シリアライザで「multilineにするということは長いのだろう」という仮定がされており、開始即改行されてしまう。
str = ''' 'That's still pointless', she said.'''
これはちょっと微妙だ。下のようになっていた方がカッコいい。
str = ''''That's still pointless', she said.'''
いやもしかしたら読みづらいかもな……?
あと、"
で括られたbasic stringの場合は、"
をエスケープシーケンスを使うか全体を"""
で括ってmultiline basic stringにするという2通りの選択肢がある。ここで常にエスケープシーケンスを使っていたが、バックスラッシュが多用されているとちょっと読みづらいので、少し考えるべきだろう。