トラック
/
Elixir
Elixir
/
演習
/
ニュースレター
ニュースレター

ニュースレター

学習演習

はじめに

File

ファイルを扱うための関数は、Fileモジュールで提供されています。

ファイル全体を読み取るには、File.read/1を使います。ファイルに書き込むには、File.write/2を使います。

File.write/2でファイルに書き込むたびに、ファイルディスクリプターが開かれ、新しいElixirのプロセスが生成されます。そのため、File.write/2を使ってループの中でファイルに書き込むのは避けましょう。

代わりに、File.open/2を使ってファイルを開くことができます。File.open/2の2番目の引数はモードのリストで、ファイルを読み取り用に開くのか、書き込み用に開くのかを指定できます。

File.open/2は、そのファイルを扱うプロセスのPIDを返します。ファイルの読み取りと書き込みを行うには、IOモジュールの関数を使い、このPIDをIOデバイスとして渡します。

ファイルの操作が終わったら、File.close/1で閉じます。

ここまでに挙げたFileモジュールの関数には、エラータプルを返す代わりにエラーを発生させる!付きの変種もあります(例:File.read!/1)。ファイルが存在しない、権限がないといったエラーを処理するつもりがない場合は、こちらの変種を使いましょう。

説明

鉄道模型が大好きで、その情熱を世界と共有しようと、ニュースレターを始めることにしました。まずは、同じ趣味を持つ友人や知人に、ニュースレターの第1号を送るところから始めます。手元には、彼らのメールアドレスの一覧が書かれたテキストファイルがあります。

1. ファイルからメールアドレスを読み込む

Newsletter.read_emails/1関数を実装しましょう。ファイルパスを1つ受け取ります。ファイルは、メールアドレスが改行で区切られて並んでいるテキストファイルです。関数は、ファイルから読み込んだメールアドレスの配列を返します。

Newsletter.read_emails("/home/my_user/documents/model_train_friends_emails.txt")
# => ["rick@example.com", "choochoo42@example.com", "anna@example.com"]

2. 書き込み用にログファイルを開く

メールの送信は、メールアドレスの打ち間違いや一時的なネットワークの問題など、予測できないさまざまな理由で失敗する可能性のある作業です。重複して送ることなく、友人全員へのメール送信をやり直せるようにするには、すでにメールを送ったアドレスを記録しておく必要があります。そのためにログファイルを使います。

Newsletter.open_log/1関数を実装しましょう。ファイルパスを1つ受け取り、書き込み用にファイルを開き、そのファイルを扱うプロセスのPIDを返します。

Newsletter.open_log("/home/my_user/documents/newsletter_issue1_log.txt")
# => #PID<0.145.0>

3. 送信済みメールを記録する

Newsletter.log_sent_email/2関数を実装しましょう。ファイルを扱うプロセスのPIDと、メールアドレスが入った文字列を受け取ります。ファイルにメールアドレスを書き込み、その後に改行を加えます。

Newsletter.log_sent_email(pid, "joe@example.com")
# => :ok

4. ログファイルを閉じる

Newsletter.close_log/1関数を実装しましょう。ファイルを扱うプロセスのPIDを受け取り、ファイルを閉じます。

Newsletter.close_log(pid)
# => :ok

5. ニュースレターを送信する

メール送信の手順を組み立てる部品がそろったので、それらを1つの関数にまとめます。

Newsletter.send_newsletter/3関数を実装しましょう。メールアドレスが書かれたファイルのパス、ログファイルのパス、そして指定されたメールアドレスにメールを送る無名関数を受け取ります。指定されたファイルからすべてのメールアドレスを読み込み、そのすべてにメールを送ろうとします。メールを送る無名関数が:okを返したら、そのメールアドレスをログファイルに書き込み、その後に改行を加えます。メールを送ったらすぐに行うようにしましょう。すべての送信が終わったら、ログファイルを閉じます。

Newsletter.send_newsletter(
  "model_train_friends_emails.txt",
  "newsletter_issue1_log.txt",
  fn email -> :ok end
)

# => :ok
GitHubで編集する リンクは新しいウィンドウまたはタブで開きます
Elixir Exercism

ニュースレターを始める準備はできましたか?

Exercismに登録すれば、58個のコンセプト168個の演習、そして本物の人間によるメンタリングとともに、Elixirを学んでマスターできます。すべて無料です。