どうもみずほです。
IOクラスのtransactionの返すHashのvalueにあたるオブジェクトが
満たすべき条件について書いてみました。
質問がこのメールの最後にあります。
=begin
= 概要
IOクラスのtransactionメソッドはブロックパラメーターとしてHashオブジェクトを返します。
このHashオブジェクトは日付をあらわす文字列をキー、日記データを値とします。
このドキュメントはtransactionメソッドの返り値に含まれる日記データが
満たすべき条件について述べます。
日記データの具体例としては tdiary/defaultio.rb で定義されている
DefaultIO::TDiaryDiary を参照してください。
= 日記データ
日記データは大まかに分けると、下のように表すことができます。
日記データ ------ 日付
|
-- タイトル
|
-- 最終更新日
|
-- 0個以上のコメント
|
-- 0個以上のReferer
|
-- 1個以上のセクション
|
-- 日記の本文
さらにセクションは下のように表すことができます。
セクション ----- サブタイトル
|
-- 著者
|
-- セクションに対応する本文
日記のデータ構造がこれと完全に同一である必要はなく、日記データが付加的なデータを持ったり、
セクションが幾つかのサブセクションに分かれたりしても良いです。
= 日記データのクラス
日記データからはその日付、タイトル、最終更新日、日記本文、
コメント、Referer、セクションをなどを参照できる必要があります。
== DiaryBaseモジュール
tdiary.rbにはDiaryBaseというモジュールが定義されており、
日記データのクラスはこのモジュールをincludeしなければなりません。
下記の例はHogeDiaryにDiaryBaseをincludeしています。
class HogeDiary
include DiaryBase
.....
end
== 最低限実装すべきもの
DiaryBaseモジュールには日記データのクラスに必要な幾つかのメソッドが
定義されています。DiaryBaseで定義されているメソッド以外に
日記データのクラスが備えるべきメソッドは下記のものになります。
(ここでいうメソッドは Public Instance Method のことです。)
* initialize
* title
* title=
* date
* replace
* append
* each_section
* to_html
* to_src
* format
メソッドではありませんが、 インスタンス変数の @last_modified には気をつけましょう。
日記データに変更があった場合に @last_modified に適切なTimeオブジェクト設定しないと、
キャッシュの更新がうまくいきません。
* @last_modified
=== initialize
日記データを初期化します。引数はIOクラスによって違うものになります。
このメソッドでは DiaryBase#init_diary を呼ばなくてはなりません。
例
class HogeDiary
include DiaryBase
.....
def initialize(date, title, body, modified = Time::now)
init_diary
.....
end
.....
end
=== title
日記のタイトルを文字列として返します。日記フォーマットがタイトルに
対応しない場合は空文字列を返すようにしましょう。
=== title=(title_str)
日記のタイトルを設定します。引数title_strは文字列です。
=== date
日記の日付を返します。返り値はTimeオブジェクトです。
=== replace(date, title, body)
日記データの日付をdateに、日記本文のソースをbodyに、タイトルをtitleに変更します。
dateはTimeオブジェクト、もしくは、日付をあらわす文字列です。body, titleは文字列です。
日記本文が変更された場合、日記本文を解釈し直す必要があります。
解釈し直す時には日記データを構成するセクションも変更されます。
=== append(body, author = nil)
日記本文を追加します。bodyは追加される日記本文です。
authorは日記を記述した人の名前で、文字列です。
authorの引数はデフォルトでnilにしなければなりません。
日記本文が変更された場合、日記本文を解釈し直す必要があります。
解釈し直す時には日記データを構成するセクションも変更されます。
=== each_section
each_section は各セクションをブロックパラメータとして返します。
下に一例を示します。ここで@sectionsはセクションを保持するArrayのオブジェクトです。
class HogeDiary
.....
def each_section
@sections.each |section|
yield(section)
end
end
.....
end
=== to_html(opt, mode = :HTML)
日記データをHTMLに変換します。引数optは設定ファイル(tdiary.conf)の内容の一部を
保持するHashオブジェクトです。引数modeはSymbolオブジェクトで、
下記のいずれかです。
* :HTML
* :CHTML
:HTMLの場合は通常のブラウザ用にHTMLに、
:CHTMLの場合は携帯端末用にcHTMLに変換しなければなりません。
optの内容によって、日記のリンク先を変更しなければならないので、注意が必要です。
=== to_src
日記の本文を返します。
=== format
日記データを記述するフォーマット名を返します。
= セクションのクラス
日記本文は幾つかのセクションに分かれます。
セクションは日記本文、セクションのタイトル、セクションを書いた人の名前
などをデータとして保持しています。
== 最低限実装すべきメソッド
以下にセクションのクラスが実装すべきメソッドを列挙します。
* subtitle
* body
* text
* author
=== subtitle
セクションのタイトルを文字列として返します。
=== text
セクションに対応する本文を返します。返り値の文字列にはタイトルと著者が含まれます。
=== body
セクションに対応する本文を返します。返り値の文字列にはタイトルも著者も含まれません。
=== author
セクションを書いた人の名前を文字列として返します。
書いた人の名前がない場合は nil を返します。
=end
質問
* 日記データをもう少し真面目に表現すべきか(罫線では不十分?)
* 日記データのセクションは1個以上か0個以上か?
* title, title= くらいはDiaryBaseで実装すべきではないか?
* replaceの引数dateはTimeオブジェクトだけでも良いのではないか?
* 日記の本文をパースするタイミングを指定するか?
(defaultioでは本文に変更があった直後、tdiary-hnfではキャッシュを書き込む直前)
* to_htmlの引数modeは文字列とSymbolのどちらが良いか?
* to_htmlの引数optによってリンク先を変更する必要があったと思う
(opt['anchor']かな?)が、こういうパラメーターは他にもあるか?
* セクションのto_s, bodyは必要か?
* セクションのtextメソッドはこのままの名前にするか?
* セクションのサブタイトルがない場合はnilで良いか?
* セクションのauthorメソッドの実装の@autherの意味は何か?
# DefaultIO::TDiarySection#author
def author
@author = @auther unless @author
@author
end
過去のMarshalのデータとの互換性?
***********************
NISHIO Mizuho
e-mail : gha@...
|