あおきです。

  In Mail "[ruby-list:15857] Re: maillib with big base64"
    kikutani / sprintmail.com wrote:

> > ないはずです。小さくすると送れるということは、たぶんサイズが
> > 原因でしょう。想像するに、行末コードが\rとかになっているのでは?
> > あるいは、\r\nの環境で\nの場合でも同様です。
> > そうすると、eachループの一回目で一気に全部読み込まれて、3MBの
> > 文字列にgsub!をかけることになるので、すさまじい負荷がかかります。
> 
> 行末は \n ですが、送れないのはたかだか8KBくらいです。

あ、外れでしたか。すみません。


> > 望ましいと思います。sendmailなど、巨大な文字列を扱う可能性のある
> > メソッドはどれも引数からeachを介して文字列を受けとることになって
> > いるので、文字列やIOにラッパーをかぶせてやるのがいいです。
> 
> 具体的にはどういうラッパーですか?

…よく考えると文字列じゃあだめですね。IOじゃないと。# ボケたか?
例えばこんな(↓)感じに、確実に一行づつ渡るようにすればOKです。

class Buffer

  def initialize( f )
    @src = f
  end

  BLOCKSIZE = 512
  TERMEXP   = /\n|\r\n|\r/o

  def each
    buf = ''
    fin = false

    while true do
      begin
        buf << @src.sysread( BLOCKSIZE )
      rescue EOFError
        break
      end

      begin
        while buf[-1,1] == "\r" do   # for \r\n
          buf << @src.sysread(1)
        end
      rescue EOFError
      end
        
      beg = 0
      pos = nil
      while pos = buf.index( TERMEXP, beg ) do
        pos += $&.size
        yield buf[ beg, pos - beg ]
        beg = pos
      end

      buf = buf[ beg, buf.size - beg ]
    end

    yield buf if buf.size > 0
  end

end


同じようなコードを過去に10回くらい書いた覚えが…  ^^;;
-------------------------------------------------------------------
あおきみねろう     site: http://www1.u-netsurf.ne.jp/~brew/mine/jp/