Треки
/
Elixir
Elixir
/
Вправи
/
Розсилка
Розсилка

Розсилка

Навчальна вправа

Вступ

Файли

Функції для роботи з файлами надає модуль File.

Щоб прочитати файл повністю, використаймо File.read/1. Щоб записати у файл, використаймо File.write/2.

Щоразу, коли ми записуємо у файл за допомогою File.write/2, відкривається дескриптор файлу і створюється новий процес Elixir. Тому запису у файл у циклі за допомогою File.write/2 варто уникати.

Замість цього файл можна відкрити за допомогою File.open/2. Другим аргументом File.open/2 є список режимів, який дає змогу вказати, чи відкриваємо ми файл для читання чи для запису.

File.open/2 повертає PID процесу, який обробляє файл. Щоб читати з файлу й записувати до нього, скористаймося функціями з модуля IO і передамо цей PID як пристрій вводу-виводу.

Коли ми завершимо роботу з файлом, закриймо його за допомогою File.close/1.

Усі згадані функції з модуля File також мають варіант із !, який спричиняє помилку замість повернення кортежу помилки (наприклад, File.read!/1). Скористаймося цим варіантом, якщо ми не збираємося обробляти такі помилки, як відсутній файл або брак дозволів.

Вказівки

Ми великі поціновувачі моделей потягів і вирішили поділитися своїм захопленням зі світом, започаткувавши розсилку новин. Почнімо з того, що надішлемо перший випуск нашої розсилки друзям і знайомим, які поділяють наше захоплення. У нас є текстовий файл зі списком їхніх адрес електронної пошти.

1. Прочитати адреси електронної пошти з файлу

Реалізуйте функцію Newsletter.read_emails/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. Вона має приймати шлях до файлу, відкривати файл для запису й повертати PID процесу, який обслуговує цей файл.

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

3. Записати надісланий лист у журнал

Реалізуйте функцію Newsletter.log_sent_email/2. Вона має приймати PID процесу, який обслуговує файл, і рядок тексту (англ. string) з адресою електронної пошти. Вона має записати адресу електронної пошти у файл, додавши після неї символ нового рядка.

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

4. Закрити файл журналу

Реалізуйте функцію Newsletter.close_log/1. Вона має приймати PID процесу, який обслуговує файл, і закривати файл.

Newsletter.close_log(pid)
# => :ok

5. Надіслати розсилку новин

Тепер, коли в нас є всі складники процедури надсилання листів, потрібно поєднати їх в одній функції.

Реалізуйте функцію 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, щоб вивчати й опановувати Elixir, а також 58 концепцій168 вправ та справжнє наставництво від людей, і все це безкоштовно.