前田です。

tmail-0.8.13で、TMail::Mail#date=を使ってdateを設定すると、encode
などに失敗しますがバグでしょうか?

irb(main):001:0> mail = TMail::Mail.load_from("/dev/null")


irb(main):002:0> mail.date = Time.now
Sat Nov 18 06:48:49 JST 2000
irb(main):003:0> mail.encoded
NameError: undefined method `mday' for nil
/usr/lib/ruby/1.6/tmail/field.rb:96:in `time2str'
/usr/lib/ruby/1.6/tmail/field.rb:476:in `do_accept'
/usr/lib/ruby/1.6/tmail/field.rb:331:in `accept'
/usr/lib/ruby/1.6/tmail/tmail.rb:160:in `accept'
/usr/lib/ruby/1.6/tmail/tmail.rb:159:in `each_header'
/usr/lib/ruby/1.6/tmail/tmail.rb:266:in `each'
/usr/lib/ruby/1.6/tmail/tmail.rb:266:in `each_header'
/usr/lib/ruby/1.6/tmail/tmail.rb:159:in `accept'
/usr/lib/ruby/1.6/tmail/tmail.rb:130:in `encoded'
(irb):3:in `irb_binding'

他にいくつかリクエストがあります。

1. encodedで出力する時にへッダの順番を指定したい。
   あるいは標準的(?)な順番に出力してほしい。
   
   現状だとHashなので順番は不定ですよね。
   Content-Typeが先頭に来たりするので、何となく気持ち悪いです。

2. (既存のメールのロードではなく)新規メールを作成する手段がほしい。

   mail = TMail::Mail.new

   とかで新規メールを作成できるとうれしいです。
   今は、

   mail = TMail::Mail.load_from("/dev/null")

   とかしてます。

3. encoded-wordのdecodeで、encoded-word間のlinear-white-spaceを無
   視してほしい。

   nkfを使ってるせいだと思うのですが、

Subject: ああああああああああああああああああああああああああああああああああああああああああああああああ

   みたいなののdecodeでlinear-white-spaceをきちんと無視してくれないようです。

4. strscan.soがない環境でも動くようにしてほしい。

   ちょっとstrscan.soと挙動が違いますが(re_matchが使えないため、
   でもs.scan(/\A.../)みたいに使ってるようなので大丈夫ですよね?)、
   こんな感じでstrscan.rbとかいうのを用意すればstrscan.soがなくて
   も動くようになると思います。

begin
  require "strscan.so"
rescue LoadError

class ScanError < StandardError; end

class StringScanner
  def initialize(str, dup = true)
    if dup
      @str = str.dup
    else
      @str = str
    end
    @rest = str
    @prev_rest = nil
    @last_match = nil
  end

  def scan(re)
    if match = re.match(@rest)
      @last_match = match
      @prev_rest = @rest
      @rest = match.post_match
      return match[0]
    else
      @prev_rest = nil
      @last_match = nil
      return nil
    end
  end

  def skip(re)
    if match = re.match(@rest)
      @last_match = match
      @prev_rest = @rest
      @rest = match.post_match
      return match[0].length
    else
      @prev_rest = nil
      @last_match = nil
      return nil
    end
  end

  def match?(re)
    if match = re.match(@rest)
      @last_match = match
      @prev_rest = @rest
      return match[0].length
    else
      @prev_rest = nil
      @last_match = nil
      return nil
    end
  end

  def getch
    if match = /./.match(@rest)
      @rest = match.post_match
      return match[0]
    else
      return nil
    end
  end

  def getbyte
    if @rest.empty?
      return nil
    else
      result = @rest[0]
      @rest = @rest[1..-1]
      return result
    end
  end

  def emtpy?
    return @rest.empty?
  end

  def rest?
    return !@rest.empty?
  end

  def rest
    return @rest
  end

  def restsize
    return @rest.size
  end

  def matched?
    return @last_match != nil
  end

  def matched
    return @last_match[0]
  end

  def matchedsize
    return @last_match[0].size
  end

  def [](n)
    return @last_match[n]
  end

  def string
    return @str
  end

  def reset
    @rest = @str
    @prev_rest = nil
    @last_match = nil
  end

  def clear
    @rest = ""
    @prev_rest = nil
    @last_match = nil
  end

  def unscan
    unless @prev_rest
      raise ScanError, "cannot unscan: not scanned yet"
    end
    @rest = @prev_rest
    @prev_rest = nil
  end
end

end

-- 
前田 修吾