Треки
/
Elixir
Elixir
/
Вправи
/
Спустошення стека
Спустошення стека

Спустошення стека

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

Вступ

Винятки

Усі помилки в Elixir реалізують Exception Behaviour. Так само, як і Access Behaviour, Exception Behaviour визначає функції зворотного виклику, які модуль має реалізувати, щоб виконати програмний контракт цієї поведінки. Щойно помилку визначено, вона має такі властивості:

  • Назва модуля визначає назву помилки.
  • Модуль визначає структуру помилки.
  • Ця структура матиме поле :message.
  • Модуль можна використовувати з raise/1 і raise/2, щоб згенерувати потрібну помилку.

Exception Behaviour також визначає дві функції зворотного виклику: message/1 та exception/1. Якщо їх не реалізовано, використовуються типові реалізації. message/1 перетворює структуру помилки на читабельне повідомлення, коли його викликають через raise. exception/1 дає змогу додати до повідомлення додатковий контекст, коли його викликають через raise/2.

Визначення винятку

Щоб визначити виняток на основі модуля помилки, скористаймося макросом defexception:

# Defines a minimal error, with the name `MyError`
defmodule MyError do
  defexception message: "error"
end

# Defines an error with a customized exception/1 function
defmodule MyCustomizedError do
  defexception message: "custom error"

  @impl true
  def exception(value) do
    case value do
      [] ->
        %MyCustomizedError{}

      _ ->
        %MyCustomizedError{message: "Alert: " <> value}
    end
  end
end

Використання винятків

Визначені помилки можна використовувати так само, як вбудовану помилку, за допомогою raise/1 або raise/2.

  • raise/1 генерує конкретну помилку за назвою її модуля, а якщо аргумент є рядком тексту (англ. string), буде згенеровано RuntimeError із цим рядком тексту як повідомленням.
  • raise/2 генерує конкретну помилку за назвою її модуля та приймає аргумент з атрибутами, який використовується, щоб отримати помилку з відповідним повідомленням.

Вказівки

Продовжуючи працювати в Instruments of Texas, ми бачимо поступ у роботі над реалізацією калькулятора зі зворотним польським записом на Elixir. Наша команда хотіла б мати змогу викликати помилки, конкретніші за загальні помилки зі стандартної бібліотеки. Ми ще дещо досліджуємо, але вже вирішили реалізувати дві нові помилки, які втілюють Exception Behaviour.

1. Помилка для ділення на нуль

Ділення числа на нуль дає невизначений результат, і команда вирішує, що найкраще подати його як помилку.

Реалізуйте модуль DivisionByZeroError з таким повідомленням про помилку: "division by zero occurred"

raise DivisionByZeroError
# => ** (DivisionByZeroError) division by zero occurred

2. Помилка в разі спустошення стека

Калькулятори зі зворотним польським записом використовують стек, щоб зберігати числа до того, як їх додадуть. Команда подає цей стек як список чисел (цілих і з плаваючою комою), наприклад: [3, 4.0]. Кожній операції потрібна певна кількість чисел у стеку, щоб виконати своє обчислення. Коли чисел у стеку не вистачає, це називається помилкою спустошення стека. Реалізуйте виняток StackUnderflowError, який надає типове повідомлення та необовʼязковий додатковий контекст

raise StackUnderflowError
# => ** (StackUnderflowError) stack underflow occurred

raise StackUnderflowError, "when dividing"
# => ** (StackUnderflowError) stack underflow occurred, context: when dividing

3. Напишіть функцію ділення

Реалізуйте функцію divide/1, яка приймає стек (список із двох чисел) і:

  • викликає помилку спустошення стека, коли в стеку недостатньо чисел
  • викликає помилку ділення на нуль, коли дільник дорівнює 0 (зверніть увагу, що стек чисел зберігається у зворотному порядку)
  • виконує ділення, коли жодної помилки не виникає
RPNCalculator.Exception.divide([])
# => ** (StackUnderflowError) stack underflow occurred, context: when dividing

RPNCalculator.Exception.divide([0, 100])
# => ** (DivisionByZeroError) division by zero occurred

RPNCalculator.Exception.divide([4, 16])
# => 4

Зверніть увагу, що порядок елементів у списку зворотний!

Редагувати через GitHub Посилання відкривається в новому вікні або вкладці
Elixir Exercism

Час розпочати Спустошення стека?

Зареєструйтеся на Exercism, щоб вивчати й опановувати Elixir, а також 58 концепцій168 вправ та справжнє наставництво від людей, і все це безкоштовно.