45
44

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ゴミコードを書いた

Last updated at Posted at 2014-02-25

なかなかゴミを出す曜日を覚えられないもんだから、これは人間の脳で処理するものじゃないな、と思い、スクリプトを書いた。言語は Ruby で書いた。

実際の要件とはちょっと異なるんだけど、今回のエントリの説明用に単純化した要件は「ゴミ曜日の当日の朝に通知されてもバタバタしそうなので、前日の夜に通知したい」といったところ。

例として、このエントリでは、ゴミの収集曜日を以下のものとする。

  • 可燃ゴミ : 水曜日・土曜日
  • 資源ゴミ : 火曜日
  • 不燃ゴミ : 第2第4月曜日

Version 1

gomi.rb
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水曜日」かもしれない。

だから「今日」ではなくて、素直に「明日」を扱った方がいい。

gomi.rb
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

gomi.rb
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

gomi.rb
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月曜日?」とか、だいぶ気軽に聞けるようになったんじゃないかなぁと思う。

45
44
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
45
44

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?