ruby-trunk-changes r54236 - r54246

今日は拡張ライブラリ date の inspect や strftime のリファクタリングや、Array#inject で Float を含む和を計算する時の誤差軽減の修正などがありました。

nobu: r54236 2016-03-23 20:57:01 +0900

Time#strftime の実装に使っている rb_strftime_with_timespec() で C の文字列として返すため呼び元でバッファの拡張が必要だったのを String オブジェクトで返すようにして内部で自動的にバッファを拡張するようにして、また NUL 文字を含む時の考慮も不要になっているようです。これまでバッファサイズ超えると Errno::ERANGE が発生していたのが発生しなくなったようです。

mrkn: r54237 2016-03-23 21:41:00 +0900

r54162 の Enumerable#inject の Array で第2引数が :+ の時の最適化を Float まで拡張したところで、浮動小数点数の和で誤差を軽減するための Kahan のアルゴリズムというのを利用するようにしています。うーむこんなノウハウがあるのか…。

mrkn: r54238 2016-03-23 21:50:24 +0900

r54237 の再修正で数値の型による分岐の外に演算の一部を括り出しています。

nobu: r54239 2016-03-24 11:43:34 +0900

r54236 の rb_strftime_with_timespec() の String オブジェクトを返すようにする変更時にバッファの終端のチェックの条件に不要なものがあったのを削っています。

svn: r54240 2016-03-24 11:43:35 +0900

version.h の日付更新。

nobu: r54241 2016-03-24 12:42:37 +0900

拡張ライブラリ date の Date#inspect, DateTime#inspect の実装でフラグの文字列化で rb_sprintf() のかわりに直接文字列バッファを使うようにしたり PRIsVALUE を使ってクラス名など文字列オブジェクトのまま埋め込むようにしてエンコーディングの保持や最適化による GC マーク漏れの回避(RB_GC_GUARD())を不要にしたりするリファクタリング

nobu: r54242 2016-03-24 12:43:06 +0900

拡張ライブラリ date での jisx0301 と iso8601 のフォーマットでフォーマット文字列の組み立てを snprintf(3) を使って簡潔に書くように修正しています。多分元は long に収まらない範囲の UNIX TIME を考慮してたので専用の演算用関数を使ってたのだと思いますが、そういう場合は "%Y-%m-%d" 固定でいいので Fixnum に収まってなかったら分岐して即返すようにしています。

nobu: r54243 2016-03-24 12:43:28 +0900

拡張ライブラリ date の dt_lite_iso8601() で文字列の連結に f_add() という関数を使ってメソッド呼び出ししてたのを rb_str_append() を直接呼び出すようにしています。

nobu: r54244 2016-03-24 13:27:35 +0900

r54242 で不要になった dt_lite_jisx0301() の get_d1() というマクロ(による変数代入)を削除しています。

nobu: r54245 2016-03-24 14:20:22 +0900

拡張ライブラリ date の rb_strftime_with_timespec() でアルファベット部分を大文字にするフラグ指定の処理を関数に切り出して再帰的呼び出し時にも伝播させるようにしているそうです。

nobu: r54246 2016-03-24 17:44:03 +0900

Time#strftime の実装でも共通部分をマクロに括り出したりするリファクタリング。 FMT_PADDING() はなんかずいぶん tricky にみえるマクロですね。わけがわからないというほどではないですが、素直に分岐して2つの文字列リテラルのどっちかを返せばよさそうなのに、なんでこんなふうにしてるんだろ…。