calコマンドとExerb + Rakefileのサンプル
UNIXでよく使われるカレンダーを表示するプログラムをRubyで実装してみました。かなり前に自分で実装したHaskell版を参考に、できるだけRubyぽさがでるように心掛けてみました。
これだけだとさみしいので、ついでにExerb + Rakefileのサンプルもつけておきます。rakeでコンパイル、rake packageで配布用のアーカイブを作成します。あ、そうそうExerb化したプログラムを圧縮するのにUPXを使っています。不要な人はRakefileの該当行を適当に削ってください。
ファイル: cal.rb
#!/usr/bin/env ruby require 'date' class Date def first_day_of_month Date.new(year, month, 1) end def last_day_of_month Date.new(year, month, ndays_of_month) end def each_days_of_month(&block) first_day_of_month.step(last_day_of_month, 1, &block) end def ndays_of_month case month when 2 leap? ? 29 : 28 when 4, 6, 9, 11 30 else 31 end end end class Calendar WEEK_HEADER = "Su Mo Tu We Th Fr Sa" def initialize(date) @fdate = date.first_day_of_month end def to_s s = '' s << @fdate.strftime('%B %Y').center(WEEK_HEADER.size) + "\n" s << WEEK_HEADER + "\n" s << ' ' * @fdate.wday @fdate.each_days_of_month do |date| s << sprintf('%2d%s', date.day, newline?(date) ? "\n" : ' ') end s << "\n" unless s[-1] == ?\n s end private def newline?(date) (date.day + @fdate.wday) % 7 == 0 end end if $0 == __FILE__ today = Date.today month = ARGV[0] ? ARGV[0] : today.month year = ARGV[1] ? ARGV[1] : today.year print Calendar.new(Date.parse("#{year}/#{month}/1")) end
ファイル: cal.exy
general: startup: cal.rb core: cui kcode: none file: cal.rb: rational.rb: file: C:/Program Files/ruby-1.8/lib/ruby/1.8/rational.rb date/format.rb: file: C:/Program Files/ruby-1.8/lib/ruby/1.8/date/format.rb date.rb: file: C:/Program Files/ruby-1.8/lib/ruby/1.8/date.rb
ファイル: Rakefile
# -*- ruby -*- require 'rake/clean' require 'rake/packagetask' task :default => ['cal.exe'] file 'cal.exe' => ['cal.rb', 'cal.exy'] do sh 'exerb.bat cal.exy' sh 'upx cal.exe' end CLEAN.include('cal.exe') Rake::PackageTask.new('cal', '0.1a') do |p| p.package_dir = './pkg' p.package_files.include('Rakefile') p.package_files.include('cal.*') p.need_zip = true end
実行例:
>cal.exe April 2007 Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30