なかなかゴミを出す曜日を覚えられないもんだから、これは人間の脳で処理するものじゃないな、と思い、スクリプトを書いた。言語は Ruby で書いた。
実際の要件とはちょっと異なるんだけど、今回のエントリの説明用に単純化した要件は「ゴミ曜日の当日の朝に通知されてもバタバタしそうなので、前日の夜に通知したい」といったところ。
例として、このエントリでは、ゴミの収集曜日を以下のものとする。
- 可燃ゴミ : 水曜日・土曜日
- 資源ゴミ : 火曜日
- 不燃ゴミ : 第2第4月曜日
Version 1
require "date"
message =
case Date.today.wday
when 0 # Sun
when 1 # Mon
"明日は「資源ゴミ」の日です"
when 2, 5 # Tue, Fri
"明日は「可燃ごみ」の日です"
when 3 # Wed
when 4 # Thu
when 6 # Sat
end
「第2月曜日、もしくは、第4月曜日」はややこしいな、と思い、そこは後回しにして、
- (火曜日は資源ゴミの日なので) 今日が月曜日だったら「明日は資源ゴミ」の旨を伝える
- (水・土は可燃ゴミの日なので) 今日が火・金だったら「明日は可燃ゴミ」の旨を伝える
の処理を書いた。これを、毎日の22時とかに実行すれば、明日のことが通知される、といった具合だ。
Version 2
続いて「第n月曜日」の処理に取りかかろうと思ったのだけれど、ここで Version 1 のコードの筋が悪いと気が付く。「今日」の曜日にもとづいて処理を進めているのがよくない。今日が「第2火曜日」だとして、明日が「第2水曜日」とは限らなくて、もしかすると「第3水曜日」かもしれない。
だから「今日」ではなくて、素直に「明日」を扱った方がいい。
require "date"
tomorrow = Date.today + 1
message =
case tomorrow.wday
when 0 # Sun
when 1 # Mon
when 2 # Tue
"明日は「資源ゴミ」の日です"
when 3, 6 # Wed, Sat
"明日は「可燃ごみ」の日です"
when 4 # Thu
when 5 # Fri
end
これで、ゴミ収集曜日の表とコードの対応が取れるようになって、脳にやさしくなった。というか Version 1 が脳にやさしくなかった。
Version 3
require "date"
tomorrow = Date.today + 1
message =
case tomorrow.wday
when 0 # Sun
when 1 # Mon
if [2, 4].include? (tomorrow.day.to_f / 7.to_f).ceil
"明日は「不燃ゴミ」の日です"
end
when 2 # Tue
"明日は「資源ゴミ」の日です"
when 3, 6 # Wed, Sat
"明日は「可燃ごみ」の日です"
when 4 # Thu
when 5 # Fri
end
こうして書いてみると、「第2月曜日」「第4月曜日」という概念はだいぶ複雑なのでは… という気になってくる。パッと見でなにをしているコードなのか理解がむつかしいので、なんとかしたい気持ちになる。「7で割ったときの商が」とか言いたいわけじゃない。もっとこう、思考しているときに近い感覚で処理を書けるといいのに…!
Version 4
require "date"
class Date
(1..5).each { |n|
define_method("第#{n}?") { (self.day.to_f / 7.to_f).ceil == n }
}
%w(日 月 火 水 木 金 土).each_with_index { |曜日, index|
define_method("#{曜日}曜日?") { index == self.wday }
}
(1..5).each { |n|
%w(日 月 火 水 木 金 土).each { |曜日|
define_method("第#{n}#{曜日}曜日?") {
self.send("第#{n}?") && self.send("#{曜日}曜日?")
}
}
}
end
明日 = Date.today + 1
targets = []
targets << "資源ゴミ" if 明日.火曜日?
targets << "可燃ゴミ" if 明日.水曜日? or 明日.土曜日?
targets << "不燃ゴミ" if 明日.第2月曜日? or 明日.第4月曜日?
message = targets.empty? ? nil : "明日は%sの日です" % targets.map { |target| "「#{target}」" }.join
「明日.第2月曜日?」とか、だいぶ気軽に聞けるようになったんじゃないかなぁと思う。