Date / Time / DateTime method coverage audit
Generated 2026-05-23 as the Phase 1 artifact of a rigor-type-coverage-uplift
session (Phase 4 / Slice 4 of the post-c9a535a coverage-uplift line).
Unlike the String / Integer / Hash / Math audits, the Date / Time conclusion is not a list of dispatch-tier additions. The reader surface is already catalog-ready; the single blocker is a missing type carrier. This document records that finding. The carrier was authorised and implemented (see § 4); the 🟦 rows below are now ✅.
| 記号 | 意味 |
|---|---|
| ✅ | Constant[Date] / Constant[Time]キャリア経由でfold済み |
| 🚫 | 非対象(破壊的・非決定的・マシン依存) |
Date / DateTime / TimeはCATALOG_BY_CLASS(constant_folding.rb)に
登録済みで、DATE_CATALOG / TIME_CATALOGがCソースから抽出済み。リーダ
メソッド群(year / month / day / hour / wday / leap? / strftime
/ iso8601 / next_day / >> …)は:leaf分類でfold適格。
それにもかかわらず精密化が起きないのは、Type::ConstantのSCALAR_CLASSES
(lib/rigor/type/constant.rb)にDate / Timeが含まれず、ConstantFolding
のfoldable_constant_value?も両クラスを受け付けないため。Date.new(2026,1,1)
はNominal[Date]止まりで、その上の.yearもRBSティアのIntegerに
広がる。
spec/integration/fixtures/date_catalog/demo.rbとtime_catalog.rbは、この
状況を「a future Constant<Date> carrier would be eligible to fold them」と
明記し、現状のNominal答えがunsound carrierを生まないことを回帰で固定して
いる。本監査はその「future carrier」を正式な判断事項として起票するもの。
2. メソッド分類(Date / DateTime)
Section titled “2. メソッド分類(Date / DateTime)”Date.new(...)の引数が全てConstant[Integer]のとき、以下がConstantに
fold可能になる(カタログ分類は確認済み・date_catalog/demo.rbが裏付け):
| 群 | メソッド | fold先 | 状態 |
|---|---|---|---|
| Integerリーダ | year month/mon day/mday wday yday cwyear cweek cwday jd | Constant[Integer] | ✅ |
| bool述語 | leap? julian? gregorian? sunday?…saturday? | Constant[bool] | ✅ |
| Stringリーダ | to_s iso8601 strftime(fmt) httpdate rfc3339 | Constant[String] | ✅ |
| Dateナビ | next_day prev_day next_month prev_year succ >> << next | Constant[Date] | ✅ |
| DateTime追加 | hour min sec offset zone | `Constant[Integer | String]` |
| 比較 | <=> == < > (Date×Date) | `Constant[bool | Integer]` |
| 破壊的 | (Dateは不変。該当なし) | — | — |
3. メソッド分類(Time)
Section titled “3. メソッド分類(Time)”Time.utc(...) / Time.gm(...) / Time.at(epoch)の引数が全て定数のとき:
| 群 | メソッド | fold先 | 状態 |
|---|---|---|---|
| Integerリーダ | year month day hour min sec wday yday usec nsec utc_offset | Constant[Integer] | ✅ |
| bool述語 | utc?/gmt? sunday?…saturday? dst? | Constant[bool] | ✅ |
| Stringリーダ | strftime(fmt) to_s ctime/asctime inspect | Constant[String] | ✅ |
| Timeナビ | getutc/getgm + -(Numeric) round floor ceil | Constant[Time] | ✅ |
| 破壊的 | localtime gmtime utc | — | 🚫 ブロックリスト済み |
| マシン依存 | getlocal | — | 🚫 TIME_CATALOGブロックリストに追加 |
| 非決定的 | Time.now / Time.at / Time.local / Time.new | — | 🚫 carrier化対象外(ローカルゾーン依存) |
Timeの不変性の注意: Time#localtime / gmtime / utcはtime_modify
でreceiverをin-place変更する。Timeは純粋不変ではない。Constant[Time]
キャリアにする場合、String / Setと同じくvalue.dup.freezeで凍結する必要
がある(凍結TimeへのlocaltimeはFrozenError → foldはrescueで
decline、健全)。TIME_CATALOGは既に3つの擬似ミューテータをブロックリスト済み。
4. 実装(carrier新設、承認のうえ実施)
Section titled “4. 実装(carrier新設、承認のうえ実施)”Date / Timeの精密化はディスパッチ層の追加では達成できず、Type::Constant
に新しいスカラキャリアを足す型システム変更が前提だった。Setキャリアの前例に
沿って以下を実装した:
-
lib/rigor/type/constant.rb- 先頭で
require "date"(Date/DateTimeはstdlib。Timeはcore)。 SCALAR_CLASSESにDate(DateTimeはDateのサブクラスなので包含)とTimeを追加。initializeの凍結分岐をfreezable_carrier?に切り出し、Date/Timeをvalue.dup.freeze対象に追加(凍結TimeへのlocaltimeはFrozenError→ foldはrescueでdecline、健全)。describeを特例化 —Date#inspectはastronomical Julian day表記で 不可読なのでiso8601("2026-01-01")を使う。Time#inspectは"2026-01-01 00:00:00 UTC"と簡潔なので既定のまま。
- 先頭で
-
constant_folding.rbfoldable_constant_value?の許可クラス集合(FOLDABLE_CONSTANT_CLASSES)にDate/Timeを追加。リーダ群はカタログ(catalog_allows?)経由で 自動的にfoldするためUNARY/BINARY Setへの追加は不要。
-
コンストラクタfold(
Constant[Date]/Constant[Time]を産む入口)Date.new(y,m,d)/DateTime.new(...)—MethodDispatcher#meta_newにdate_new_lift(range_new_lift/regexp_new_liftと同じ場所・同じ形)。Time.utc(...)/Time.gm(...)— Tier DTimeFoldingモジュール (dispatch_stdlib_module_tiersに配線)。UTC固定なのでマシン非依存。Time.now/Time.at/Time.local/Time.new/Date.today/Date.parseは対象外 — 非決定的、またはローカルゾーン依存。
-
FP規律 — マシン依存の排除
Time.utc/gmのみをfold(UTC固定)。Time.at/Time.local/Time.new(明示オフセットなし)は解析マシンのゾーンに依存するため非対象。Time#getlocalをTIME_CATALOGのブロックリストに追加 — ミューテータでは ないが結果が解析マシンのゾーンに依存するため、Constant[Time](常にUTC) からfoldするとホスト依存の値が型に焼き込まれる。getutc/getgmは UTC結果なのでfold可能なまま。rigor check libクリーン、4345 examples 0 failuresで回帰固定。
© 2026 TypedDuck. Licensed under CC BY-SA 4.0.