Kazuhiko
kazuh****@fdiar*****
2003年 6月 7日 (土) 22:18:11 JST
かずひこです。 懸案の Daily クラスへの移行パッチおよびデータ変換スクリプトを送ります。 おおざっぱに言えば、Daily クラスを新設したうえで、Monthly クラスを変更し ただけです。つまり、外から見た API は変わらないように、Monthly クラスの メソッドの中身を変更しています。 Monthly クラスのインスタンスは、これまで Item クラスのインスタンスを一月 分 Array で蓄えていましたが、それを Daily クラスのインスタンスを一月分 Hash (key は YYYYMMDD) で蓄えるようにしました。ただ、速度的な面で? 従来 のように Array で持った方がいいのかどうか悩み中です。 Item クラスは、もはや date を保持しなくてもよくなりましたが、今のところ そのまま持たせています。というのは、Monthly::add( item ) というこれまで の API との互換性のためです。 そんなわけで、ちょっと確認してくださいますか? あと、速度が遅くなったように感じるかどうかもお知らせくださいませ。 よろしくお願いします。 -- かずひこ <http://wiki.fdiary.net/kazuhiko/> ★シャア「名字が付いてない」 ☆一兵卒「あんなの飾りです。偉い人にはそれが分からんのです」 ==================== 変換スクリプト (conv3.rb) ==================== #!/usr/bin/env ruby # データファイルを Daily クラス版用データファイルに変換するスクリプト # # 使い方 # # このスクリプトを mobo.rb と同じディレクトリに置き、変換したいデータベー # スファイル (YYYYMM.db) も同じディレクトリにコピーする。変換後のファイ # ルは、new/ ディレクトリ内に作成されるので、data_path で設定したディレ # クトリにコピーしてください。 require 'pstore' require 'mobo' module MoBo class Monthly def items @items end end unless FileTest::directory?( 'new' ) then Dir::mkdir( 'new' ) end Dir::glob( "??????.db" ).each do |f| db = PStore::new( f ) db.transaction do begin @monthly = db['mobo']; rescue; end end next unles****@month*****_size > 0 @monthly_new = Monthly.new ( @monthly.month ) @monthly.items.sort.each do |i| date = "#{@monthly.month}#{sprintf('%02d',i.date)}" @diary = @monthly_new[ date ] || Daily.new( date ) @diary.add( i ) @monthly_new[ date ] = @diary end db = PStore::new( "new/#{f}" ) db.transaction do begin db['mobo'] = @monthly_new; rescue; end end print "#{@monthly_new.month}\n" end end ==================== パッチ (mobo.rb.diff) ==================== Index: mobo.rb =================================================================== RCS file: /cvsroot/mobo/mobo/mobo.rb,v retrieving revision 1.10 diff -u -r1.10 mobo.rb --- mobo.rb 2 Jun 2003 14:20:55 -0000 1.10 +++ mobo.rb 7 Jun 2003 13:04:11 -0000 @@ -123,20 +123,18 @@ end def <=>( other ) - t =****@date*****_i <=> other.date.to_i - return t if t != 0 return @genre <=> other.genre end end # - # class Monthly + # class Daily # - class Monthly - attr_reader :month - def initialize( month ) - raise ArgumentError::new( 'Bad month' ) if (/^\d{6}$/ !~ month) == nil - @month = month + class Daily + attr_reader :date + def initialize( date ) + raise ArgumentError::new( 'Bad date' ) if (/^\d{8}$/ !~ date) == nil + @date = date @items = [] end @@ -144,10 +142,6 @@ @items << item end - def []( idx ) - @items[idx] - end - def each_item( cond = {} ) @items.sort.each do |i| flag = true @@ -156,6 +150,47 @@ flag = (i.send(key) =~ val) && flag end yield i if flag + end + end + end + + # + # class Monthly + # + class Monthly + attr_reader :month + def initialize( month ) + raise ArgumentError::new( 'Bad month' ) if (/^\d{6}$/ !~ month) == nil + @month = month + @diaries = {} + end + + def add( item ) + date = "#{month}#{sprintf('%02d',item.date)}" + diary = @diaries[date] || Daily.new( date ) + diary.add( item ) + @diaries[date] = diary + end + + def []( date ) + @diaries[date] + end + + def []=( date, diary ) + @diaries[date] = diary + end + + def each_diary( cond = {} ) + @diaries.sort.each do |date,diary| + yield diary + end + end + + def each_item( cond = {} ) + @diaries.sort.each do |date,diary| + diary.each_item( cond ) do |i| + yield i + end end end