💡
[Misc #21325] `Time#strftime` を `Time#format` という名前で利用したいというチケット
[Misc #21325] make ruby more middle-aged man friendly
- タイトルはアレなんですが内容は
Time#strftimeをTime#formatという名前で利用したいというチケット -
Time#strftime時刻の情報を任意のフォーマットに変換するようなメソッドですね
time = Time.new(2025, 5, 2)
pp time.strftime("%Y-%m-%d") # => "2025-05-02"
pp time.strftime("%y/%m/%d") # => "25/05/02"
- そもそもなんですが現状だと
Kernel.#formatが別に private メソッドとして定義されているんですよねー- こっちは
Kernel.#sprintfの alias として定義されています
- こっちは
- なので
Timeに対して#formatは以下のように動作します
class Time
def hoge
# これは 1000 の値を %04x というフォーマットで変換しているだけ
p format("%04x", 1000)
# => "03e8"
end
end
Time.now.hoge
# format は private メソッドなので外から呼び出すことはできない
# error private method 'format' called for an instance of String (NoMethodError)
Time.now.format("%04x", 1000)
-
#formatはレシーバに依存せず関数ライクな形で利用するみたいな想定ですねー - 対応するとすれば
Time#formatを再定義するのか別の名前で定義するのか、みたいな選択肢になりそう - ふと思ったけど『
privateメソッドをレシーバ付きで呼び出すと#method_missingが優先して呼ばれる』を利用すると以下ように『formatという名前は同じだがレシーバありとなしで使い分けできる』みたいなことは実現できそう- これがいいかどうかは置いといて
class Time
def method_missing(name, ...)
if name == :format
strftime(...)
else
super(name, ...)
end
end
def hoge
# レシーバがない場合は Kernel.#format が呼び出される
pp format("%04x", 1000) # => "03e8"
end
end
Time.now.hoge
# レシーバがある場合は method_missing 経由で Time#strftime が呼ばれる
pp Time.now.format("%Y-%m-%d") # => "2025-06-04"
Discussion