CHANGELOG v0.32.1
2019/12/18
[原文]
標準ライブラリ
コレクション
Enumerable#each_cons_pair
と Iterator#cons_pair
のドキュメントを修正(#8585)
ネットワーク
HTTP::WebSocket
の on_close
コールバックが、エラーが起きた際に必ず呼ばれるようになった(#8552)
通信中、エラーで予期せず終了した場合に、on_close
に記述した後処理がトリガされないの辛くネ?
OpenSSL 1.1 以上を使用する際に発生する spec の散発的なエラーを修正#8582)
OpenSSL 側の TLS1.3 の挙動に対応するため。
コンパイラ
言語仕様
式展開の前に隣接する文字列リテラルを連結するようにした(#8581)
おそらく v0.32.1 のリリースが急がれた直接の原因。
v0.32.0 で文字列リテラル内の式展開の内部実装が、String.build
で逐次連結する方式から String.interpolation
を使用する方式に変更になった。こうすると、コンパイラに手を入れなくても式展開の実装を変更できるようになる。
さてこの時、String.interpolation
の引数は、文字列リテラルを地の文字列部分と展開式部分に分解したもの。
"I'm #{age} years old."
# ↓ 同じ
String.interpolation("I'm ", age, " years old.")
文字列リテラルの構成によって、この時の引数の数や型の組み合わせが変わってくるため、これを受けるメソッドの定義は def self.interpolation(*values : *T) forall T
となっていて、上の例で age
が Int32
型であれば、この場合の引数 values
の型は Tuple(String, Int32, String)
だとコンパイラは推定する。
Tuple(*T)
型は可変長の型引数を持つジェネリック型の1種で、この 可変長の型引数 は「指定できる個数が最大300」という制約があるらしい。1つのリテラルに150箇所近く式を埋め込まめる計算になるので、普通にクオータで括った文字列リテラルを使っている分にはほぼ顕在化しない制約なんだけど、問題はコンパイラがヒアドキュメントの各行をそれぞれ別の文字列リテラルとして認識する点。
行数の多いヒアドキュメントが存在すると、実用中にこの制約が顕在化してしまう可能性がある。
ということで、文字列リテラルの構成要素の中に連続する文字列リテラルがあったら、予め1つに結合してから String.interpolation
に渡すよう変更された。