Ruby勉強会@関西 #21に参加
してきました。
初Matzにちょっと興奮しました。気付いてみれば世界のMatzですもんね。あのノリでRubyを新しい方向に導いたりしているわけなんですね。突然、SymbolがStringのサブクラスになっちゃったりして驚かされたりするわけですが、何となく納得できました。はい。
cuzicさんの初心者レッスン。資料・題材とも良くできていたかと思います。ただ、何か「ネタ」な印象の方が強かったのはなぜなんでしょう?(^^;
久しぶりに初心者レッスンの課題をやってみました。結局時間内には書ききれず、帰りの電車までお持ち帰りしましたが、概ね書き終えましたので、整形したものを晒しておきます。
ぎゃくっく(Date#>>(n))がnヶ月先のDateオブジェクトを返すことは知っていたのですが、loopの課題だったので、cuzicさん同様、day=1になるまでインクリメントする戦略を採用しています。
表示ロジックが汚すぎたので、メソッドでバラバラにしてみましたが、まだイマイチです。
インタフェースとしては、引数の数に合わせて、「0:今月」「1:年指定」「2:年・月指定」を用意していますが、その他のオプションは用意していません。
nヶ月分のカレンダーを水平方向に並べるためには、大きめの変更が必要となってしまったのが、心残りです。
require 'date' require 'enumerator' class Cal MONTH_NAMES = %w(January Febrary March April May June July August September Octover November December ) WDAY_NAMES = %w(Su Mo Tu We Th Fr Sa) N_WDAY = WDAY_NAMES.size WIDTH_ONE_DAY = 3 def self.display(year=nil, month=nil) year = Date.today unless year if year.kind_of? Date month = year.month year = year.year self.display_year_and_month(year, month) elsif month self.display_year_and_month(year, month) else self.display_year(year) end end def self.display_year(year) 1.upto(MONTH_NAMES.size) do |m| cal = self.new(year, m) cal.display end end def self.display_year_and_month(year, month) cal = self.new(year, month) cal.display end def initialize( year, month ) @body = Date.new(year, month, 1) end def display first_wday = find_first_wday puts year_line puts month_line puts wday_names_line puts all_weeks_lines(first_wday) end def find_first_wday @body.wday end def last_day?(date) if (date + 1).day == 1 true else false end end def find_last_day last_day = @body.dup loop do last_day += 1 break if last_day? last_day end last_day end def year_line (" " * ((WIDTH_ONE_DAY * N_WDAY - @body.year.to_s.length )/ 2)) << @body.year.to_s end def month_line nmonth = MONTH_NAMES[@body.month - 1] (" " * ((WIDTH_ONE_DAY * N_WDAY - nmonth.length) / 2)) << nmonth end def wday_names_line ret = ("%2s " * N_WDAY) % WDAY_NAMES ret.chop end def before_first_day(first_wday) ret = " " * (WIDTH_ONE_DAY * first_wday) end def first_week_line(first_wday) ret = before_first_day(first_wday) nokori_first_week = N_WDAY - first_wday ret << "%2s " * (nokori_first_week) % (1..(nokori_first_week)).to_a ret.chop! end def nokori_week_line(nokori_first_week) ret = "" (nokori_first_week..find_last_day.day).each_slice(N_WDAY) do |days| ret << "%2s " * (days.size) % days ret.chop! << "\n" end ret end def all_weeks_lines(first_wday) nokori_first_day_week = N_WDAY - first_wday + 1 first_week_line(first_wday) << "\n" << nokori_week_line(nokori_first_day_week) end end def main0 puts "test case" today = Date.today puts "Display Calendar of current month" Cal.display; puts puts "Display Calendars in 2007" Cal.display(2007); puts puts "Display Calendar of 30 days ago" Cal.display(today - 30) end def main1 params = [ARGV.shift, ARGV.shift] params.map!{|x| x.to_i if x } Cal.display(*params) end if $0 == __FILE__ main1 end