From: Shugo Maeda Date: 2003-04-28T15:49:43+09:00 Subject: [ruby-list:37628] Re: net/imapのTHREAD Extension 対応 前田です。 At Sun, 27 Apr 2003 14:33:57 +0900, wanowa.kimura@nifty.ne.jp (kimura wataru) wrote: >  net/imapをTHREADコマンドに対応させるために、以下のメソッドを > 追加してみました。 > > Net::IMAP#thread(argorithm, search_keys, charset) > Net::IMAP#uid_thread(argorithm, search_keys, charset) > > argorithmには"REFERENCES"または"ORDEREDSUBJECT"が指定できます。 おお、すばらしい。 >  返値の構造などいまいち確信が持てないので、みなさんのコメントが > いただければと思います。 一点だけ気になったところがあるのですが、 def thread_branch(token) rootmember = nil lastmember = nil add_member = proc {|seqno| newmember = ThreadMember.new(seqno, []) if rootmember.nil? rootmember = newmember else lastmember.children << newmember end newmember } while true shift_token # ignore first T_LPAR token = lookahead case token.symbol when T_NUMBER lastmember = add_member.call(number) when T_SPACE # do nothing when T_LPAR if rootmember.nil? # dummy member lastmember = add_member.call(nil) end lastmember.children << thread_branch(token) when T_RPAR break end end return rootmember end 上記のようにthread_branchの中で毎回Procオブジェクトを生成していま すが、ThreadTreeのようなクラス(名前が適切かわかりませんが)を用意 して、このクラスのメソッドにコードを移動してはどうでしょうか? たとえば、以下のようなイメージです。 # テストしていませんので、このままでは動かないかも。 class ThreadTree attr_reader :root, last def initialize @root = nil @last = nil end def add_member(seqno) newmember = ThreadMember.new(seqno, []) if @root.nil? @root = newmember else @last.children.push(newmember) end @last = newmember end def add_subthread(member) if @root.nil? # dummy member add_member(nil) end @last.children.push(member) end end .... def thread_branch(token) thread_tree = ThreadTree.new while true shift_token # ignore first T_LPAR token = lookahead case token.symbol when T_NUMBER thread_tree.add_member(number) when T_SPACE # do nothing when T_LPAR subthread = thread_branch(token) thread_tree.add_subthread(subthread) when T_RPAR break end end return thread_tree.root end -- 前田 修吾