From: "akira yamada / やまだあきら" Date: 1997-10-17T20:37:10+09:00 Subject: [ruby-list:5042] Re: mail address class やまだあきらです. しばし間が空きましたが再びメール解析用のスクリプトのお話です. Thu, 25 Sep 97 11:50:36 +0900 頃の Mail-Count: 04637 Subject: [ruby-list:4637] Re: mail address class についてのお話にて 石塚圭樹 さん曰く… (石 == keiju@bc.mbn.or.jp (石塚圭樹 ) さん) In article 04637, <199709241419.XAA10620@penta.tyo.otc.ogis-ri.co.jp> 石> そうですね. クラスの構造などは一度になかなか決められないなと感じていま 石> す. 私も, 最初クラスで作っていて後からモジュールにしたりすることは良く 石> あります. はい, 石塚さんにいろいろうかがいながら 頻繁にあっちこっち移動してたりします. 石> C++などと違ってrubyはかなり動的な言語であることと, クラス/モジュールの 石> 構成に関して自由度が高いので, 実際に機能がはっきりしてきてからでも遅く 石> ないと思っています. そうですね. 最終的には実際の使用例を作ってみないとわからないですね. # ……ruby な ML サーバプログラム? (^_^;) なお, サイズもサイズになってきましたので 今回は Web の方に置いてみました. です. さて, 内容についてですが: 石> [全体として] 石> 前回はAddressクラスがありましたが今度はHeaderクラスになりましたね. 石> 石> 正直いってこの段階では, Headerクラスの必要性はないと思います. class 石> RFC822にHeaderの機能をマージした方が良いと思います. その後考えてみて, Header クラスをやめて RFC822 クラスにマージしました. おっしゃる通り, 少なくとも現状では Header と Body に クラス別けしてしまう必要はなさそうに思えたためです. でもって 石> 個人的にはAddressクラスは残しておいた方が良かったんではないかと思って 石> います. (正規化された)文字列としてHeaderの中にアドレスのパーズ機能を持 石> たせるよりも, クラスとして独立させてAddressクラスにアドレスのパーズ機 石> 能を持たせた方が(Headerもスリムになりますし)すっきりすると思います. ま この辺りも取り入れさせてもらいまして Address クラスを復活させました. (以下個々に) >> module RFC822_staff 石> 今は定数だけですが, ここで定義されるメソッドがあるとさらにモジュールら 石> しくなるんですけどね. Header を RFC822 にマージして Address を復活させた関係で 一部のメソッドを RFC822_staff モジュールに移動してみました. # 適当かどうかはまだわかりませんが. 石> [1] >> class Header >> attr :header >> … >> include RFC822_staff 石> classの直後にincludeがある方が好きです. /usr/local/lib/ruby 配下をみても attr が こういった位置にあるのは特異(^_^;)なようですので そのようにしました. 石> [2] >> @date = >> Header.date_to_gmtime(@header['Date']) if @header.key?('Date') >> @subject = @header['Subject'] if @header.key?('Subject') 石> で十分です. 気になるのは@dateは良いとして, @subjectをインスタンス変数 石> として割り当てなくても良いのでは? って感じがします. その通りですね. 石> [5] >> def make_reply_header #(my_address) >> if r = self.get_address('Reply-to') >> h += "To: " + r + "\n" >> elsif r = self.get_address('From') >> h += "To: " + r + "\n" >> end 石> 石> Header#get_address()は配列を返すんですよね... Reply-toやFromは, 通常は 石> 1アドレスなので, これで動作しているんですが... 明示的に: 石> 石> h += "To: " + r[0] + "\n" 石> 石> としておいた方が無難かと... この辺りはとりあえずのテスト用でしたので. 石> あと, += よりは, String#concatの方が実行効率は良いです. 今回のような場 石> 合はconcatを用いても間違いはないでしょう. 了解です. そう言うことを知りませんでした. 石> あと, 勝手な要望ですが, MHの様に自分でカスタマイズが行いやすい構造になっ 石> ていると嬉しいですね. 私もそう思います. が, これはどういうふうに実装するのが嬉しいですかね? mew(ヒェ〜)のコードをみると (defvar mew-noreplyto-to-list '("From:") "*To: field list picked at mew-summary-reply if Reply-To: doesn't exist.") (defvar mew-noreplyto-cc-list '("To:" "Cc:" "Apparently-To:") "Cc: field list picked at mew-summary-reply if Reply-To: doesn't exist.") (defvar mew-replyto-to-list '("Reply-To:" "From:") "*To: field list picked at mew-summary-reply if Reply-To: exists.") (defvar mew-replyto-cc-list '("To:" "Cc:" "Apparently-To:") "*Cc: field list picked at mew-summary-reply if Reply-To: exists.") なんてなってるのですが, まねするというのも手かな? 石> [8] >> def <=>(o) 石> Integer <=> aRFC822 石> 石> などが, 実現できていませんよね? なるほど. 石> Integer#<=>(other)は, 当然, Integerのメソッドなので定義はできません(実 石> 際にはできますが, それはおいておいて). そのかわり, 自分が知らないクラ 石> スが来ると, x, y = other.corece(self)を呼びだし x<=>yを実行するように 石> なっています. Rationalの場合を例にとると, Rational#coerce(other)は: この辺りまねてみましたがどうでしょう? 石> [9] >> とりあえず mbox 形式は考えていません. 石> これからメイラを作るんだったら, ファイル形式を自由に選べる方がベストで 石> すね. えーと, RFC822 なメッセージの解析をするためのもの と考えていますので mbox 形式は対応しないと思います. MUA などで適宜分割した上で RFC822 クラスを使うってので 十分んかなぁ,と. 石> [10] >> # まだエラー処理, その他はいっさいしていません. 石> 確かに, もうそろそろ考えた方が良いかも... う… まだしてません. 明らかに異常(ファイルがないとか)の場合はともかくとして アドレス解析の経過でエラーが出た場合なんてのは どう対処するのがいいのかなあ? などと悩んでいたりします. 一律にエラーを提示して終了しちゃうってのもなんだしなあ. エラーがあったフィールドを無視するとか, エラーがあったら止まっちゃうとかの切り替えができるといいのかな? 石> [11] >> ## o multipart ボディを扱える (まだ, やってない) 石> ここをどのように扱うかが, 興味ありますね. multipart の場合は boundary で分割して RFC822 な子供のクラスを作るのかなあ. t = RFC822.new(hoge) part_i = t.part[1] part_ii = t.part[2] とか…? # t.part[0] は body の中の最初のパートまでの部分? multipart はまだよいとして, 分割されてる方は どう扱うのがよいのだろう??? # 「?」ばっかりだ…(;_;) -- やまだ あきら (akira@linux.or.jp or akira@nurs.or.jp) Linux 関連ページ