methods=
sublibraries=
requires=
classes=Net=POP3,Net=APOP,Net=POPMail,Net=POPError,Net=POPBadResponse,Net=POPAuthenticationError
is_sublibrary=false

メールを受信するためのプロトコル
POP3 (Post Office Protocol version 3) を扱うライブラリです。

POP3 の実装は [[RFC:1939]] に基いています。

=== 使用例

==== メールの受信

以下のコードは、メールを受信してファイル 'inbox/1' 'inbox/2'... に
書きこみ、サーバ上からメールを消します。pop3.server.address は適宜
読みかえてください。

  require 'net/pop'
  
  pop = Net::POP3.new('pop3.server.address', 110)
  pop.start('YourAccount', 'YourPassword')          ###
  if pop.mails.empty?
    $stderr.puts 'no mail.'
  else
    pop.mails.each_with_index do |m, idx|
      File.open("inbox/#{idx + 1}", 'w') {|f|
        f.write m.pop
      }
      m.delete
    end
    $stderr.puts "#{pop.mails.size} mails popped."
  end
  pop.finish                                        ###

POP サーバはネットワークのむこうに存在するので、
なにか仕事をさせるにはその前に開始手続きを、
終わったら終了手続きを、行わなければいけません。
それを行うのが [[m:Net::POP3#start]] と [[m:Net::POP#finish]] で、
POP3 オブジェクトはその二つのメソッドの間でだけ有効になります。

サーバ上のメールは POPMail オブジェクトとして表現されており、この
オブジェクトのメソッドを呼ぶことでメールを取ってきたり消したりする
ことができます。[[m:Net::POP3#mails]] はこの POPMail オブジェクトの配列であり、
[[m:Net::POP3#each_mail]] はさらに pop.mails.each のショートカットです。

==== 短くする

上の例はあえて省略や短縮用メソッドを避けたためにかなり冗長です。
まず、ブロック付きの [[m:Net::POP3.start]] を使うことで
POP3.new, #start, #finish を併合できます。

  require 'net/pop'
  
  Net::POP3.start('pop3.server.address', 110,
                  'YourAccount', 'YourPassword') {|pop|
    if pop.mails.empty?
      $stderr.puts 'no mail.'
    else
      pop.mails.each_with_index do |m, idx|
        File.open("inbox/#{idx + 1}", 'w') {|f|
          f.write m.pop
        }
        m.delete
      end
      $stderr.puts "#{pop.mails.size} mails popped."
    end
  }

[[m:Net::POP3#delete_all]] を使うと
さらに [[m:Net::POP3#each_mail]] と
[[m:Net::POP3#delete]] を併合できます。

  require 'net/pop'
  
  Net::POP3.start('pop3.server.address', 110,
                  'YourAccount', 'YourPassword') {|pop|
    if pop.mails.empty?
      $stderr.puts 'no mail.'
    else
      i = 0
      pop.delete_all do |m|
        File.open("inbox/#{i}", 'w') {|f|
          f.write m.pop
        }
        i += 1
      end
    end
  }

クラスメソッドの [[m:Net::POP3.delete_all]] を使うとさらに短くなります。

  require 'net/pop'
  
  i = 0
  Net::POP3.delete_all('pop3.server.address', 110,
                       'YourAccount', 'YourPassword') do |m|
    File.open("inbox/#{i}", 'w') {|f|
      f.write m.pop
    }
    i += 1
  end

==== ファイルに直接書く

これまでの例では [[m:Net::POPMail#pop]] を使い、
メールをひとつの文字列としてうけとっていました。
しかし、もしメールが 100MB を越えるような巨大なメールだった場合、
この方法ではまずいかもしれません。
そのような場合は以下のように [[m:Net::POPMail#pop]] に
File オブジェクトを与える手が使えます。

  require 'net/pop'

  Net::POP3.delete_all('pop3.server.address', 110,
                       'YourAccount', 'YourPassword') do |m|
    File.open('inbox', 'w') {|f|
        m.pop f   ####
    }
  end

==== APOP を使う

Net::POP3 クラスのかわりに Net::APOP クラスを使うと、
認証時に APOP を使うようになります。
また動的にノーマル POP と APOP を選択するには、
以下のように [[m:Net::POP3.APOP]] メソッドを使うのが便利です。

  require 'net/pop'
  
  # use APOP authentication if $isapop == true
  pop = Net::POP3.APOP($isapop).new('apop.server.address', 110)
  pop.start(YourAccount', 'YourPassword') {|pop|
    # 残りのコードは同じ
  }

この方法はクラス自体を変えるので、クラスメソッドの start や foreach、
delete_all、auth_only なども APOP とともに使えます。
