Створення Elixir-додатки на прикладі. Від ініціалізації до публікації

image
Пишу цю статтю для того, щоб закріпити знання, отримані в процесі вивчення мови Elixir та його інфраструктури. Сподіваюся, що дана стаття буде корисна програмістам вирішили писати Elixir-програми.
Вступ
"Elixir — динамічний, функціональний мова програмування, розроблений для створення масштабованих і легко підтримуваних систем." — elixir-lang.org
Використовуючи Elixir для створення ваших додатків ви обов'язково зіткнетеся з Mix. Він стане вам незамінним помічником, так як через нього ви зможете виконувати такі команди як створення, збирання, тестування та публікація додатків, а також управління залежностями і багато іншого. Якщо ви знайомі з Ruby, то цей інструмент дуже схожий на Bundler, RubyGems і Rake, разом узяті. У двох словах Mix — це зручний інструмент, який поставляється з Elixir і виконує не менше завдань, ніж швейцарський ніж.
Ініціалізація нового додатка
Шаблон свого майбутнього mix-додатки найпростіше створити з допомогою команди 'mix new app_name'.
$ mix new quadratic_equation

Ця команда створить свого роду кістяк вашого додаток. А саме папку з назвою quadratic_equation і наступною структурою файлів і папок:
.gitignore # список файлів ігнорованих гитом
README.md # опис програми в стилі markdown
config/
config.exs # конфігурації програми і залежностей
lib/
quadratic_equation.ex # модуль верхнього рівня вашої програми
mix.exs # mix-файл c переліком зовнішніх залежностей
test/
quadratic_equation_test.exs # тести на модуль верхнього рівня
test_helper.exs # конфігурації і допоміжні засоби тестів

Є кілька угод про імена та зміст файлів, знання яких вам знадобляться:
  • Використовуйте ім'я головного модуля програми в іменах подмодулей для зменшення ймовірності колізії імен;
  • Кожен модуль повинен розташовуватися в окремому файлі, і зворотне, кожен файл повинен містити один модуль;
  • Імена файлів повинні бути в snake_case стилі;
  • назви модулів повинні бути в CamelCase стилі;
  • Структура папок повинна повторювати іменну структуру модулів.
Дотримуйтеся прийняту структуру в додатках, і це дозволить компілятору здійснювати завантаження коду без зайвих помилок.
Тестування програми
Для розміщення тестів при генерації нового mix-додатки була створена папка
test/
. Тестування програми є важливою (але не невід'ємної) частиною написання працездатного (але не обов'язково якісного) коду.
Запуск тестів здійснюється командою
mix test
з кореневої папки програми, для більш інформативного виводу використовується опція
--trace
.
$ mix test --trace

Це команда також створить папку
_build
і скомпилирует в неї вашу програму в середовищі помістивши все
.beam
файли.
Монтаж і запуск програми в iex
iex — це інтерактивна консоль для роботи з додатками, що постачається разом з Elixir. Щодо Ruby це аналог irb.
Запустити mix-додаток можна за допомогою команди
iex -S mix
. Дана команда попередньо скомпилирует ваш код, якщо це потрібно, і запустить інтерактивну консоль, подгрузив в неї ваш додаток.
$ iex -S mix
Erlang/OTP 19 [ea-8.1] [source-e7be63d] [64-bit] [async-threads:10] [hipe] [kernel-poll:false]

Interactive Elixir (1.3.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> 

Окремо скомпілювати ваш додаток можна командою
mix compile
.
Написання коду програми
В силу простоти додатка, весь код ми будемо розміщувати в тілі модуля верхнього рівня, а саме в QuadraticEquation.
# lib/quadratic_equation.ex

defmodule QuadraticEquation do
@moduledoc """
The module with the logic of the solution of the equation quadratic
"""

end

Для поставленої задачі нам потрібно 1 публічна і кілька приватних функцій. Публічна функція буде містити логіку рішення рівняння, а приватні функції будуть виводити на екран початковий квадратне рівняння і варіанти отриманих рішень.
Мабуть почнемо з написання тестів. Як раз визначимося з варіантами відповідей нашого публічного методу. Тести ми будемо розміщувати в спеціальному файлі згенерованим для модуля верхнього рівня.
# test/quadratic_equation_test.exs

defmodule QuadraticEquationTest do
use ExUnit.Case
doctest QuadraticEquation

end

З курсу школи ми пам'ятаємо, що квадратне рівняння має два, іноді однакових, кореня, або не має рішення зовсім.
# test/quadratic_equation_test.exs

defmodule QuadraticEquationTest do
use ExUnit.Case
doctest QuadraticEquation

test "when discriminant less than zero" do
assert QuadraticEquation.calculation(1, 2, 3) ==
{:fail, [error: "Discriminant less than zero!"]}
end

test "when discriminant equal zero" do
assert QuadraticEquation.calculation(2, 4, 2) ==
{:success, [x1: -1.0, x2: -1.0, d: 0.0]}
end

test "when discriminant more than zero" do
assert QuadraticEquation.calculation(2, 3, 1) ==
{:success, [x1: -0.5, x2: -1.0, d: 1.0]}
end
end

Не будемо запускати тести прямо зараз, для початку визначимо функцію calculation в QuadraticEquation. Дана функція буде приймати три числові значення, а саме змінні a, b і з властиві квадратному рівнянню в традиційній формі запису.
# lib/quadratic_equation.ex

...
@doc """
See the description of the module.
"""
def calculation(a, b, c) do
end
...

Тепер запустимо тести і переконаємося, що вони не пройшли.
Додамо рішення квадратного рівняння в нашу функцію. А також вкажемо очікувані нашими тестами повертає значення функції.
# lib/quadratic_equation.ex

...
def calculation(a, b, c) do
# print_equation(a, b, c)

d = :math.pow(b, 2) - 4 * a * c

if d >= 0 do
x1 = (-1 * b + :math.sqrt(d)) / (2 * a)
x2 = (-1 * b - :math.sqrt(d)) / (2 * a)

# print_success(x1, x2, d)

{:success, [x1: x1, x2: x2, d: d]}
else
# print_fail(d)

{:fail, [error: "Discriminant less than zero!"]}
end
end
...

Приватні функції визначаються за допомогою наступної конструкції ...
defp method_name do
end

Не буду приводити приватні методи в статті, вони є у вихідному коді прикладу на GitHub.com.
Примітка. Анотації
@moduledoc
та
@doc
необхідні для розгорнутого опису суті модуля і для опису суті функції.
Створення mix завдання
Написання завдання для даного прикладу коду не є обов'язковою, але для статті у загальному дана частина буде корисна.
У mix-додатках всі завдання прийнято розташовувати в призначеній для цього папці lib/mix/tasks. Так що насамперед додайте цю папку собі в додаток.
$ mkdir -p lib/mix/tasks

Потім створіть у папці для завдань файл з ім'ям містить ім'я основного модуля програми і назва завдання.
$ touch lib/mix/tasks/quadratic_equation.example.ex

Завдання буде не складною, в її обов'язки входить виклик функції calculation модуля QuadraticEquation.
# lib/mix/tasks/quadratic_equation.example.ex

defmodule Mix.Tasks.QuadraticEquation.Example do
use Mix.Task

@shortdoc "QuadraticEquation. Example of calculation."

def run(_) do
QuadraticEquation.calculation(2, 3, 1)
end
end

Анотація
@shortdoc
необхідна як для короткого опису суті вашої задачі, так і для того, щоб вона почала відображатися в списку виводу команди
mix help
.
$ mix help

Публікація програми в Hex
Hex — бібліотека Erlang і Elixir додатків.
Перед тим як опублікувати свою mix-додаток mix.exs файл необхідно додати опис і метадані проекту. Частина метаданих було згенеровано автоматично командою
mix new ...
.
# mix.exs

@version "0.1.0"

def project do
[app: :quadratic_equation,
версія: @version,
elixir: "~> 1.3",
build_embedded: Mix.env == :prod,
start_permanent: Mix.env == :prod,
package: package,
homepage_url: "https://hexdocs.pm/quadratic_equation",
source_url: "https://github.com/folklore/quadratic_equation",
description: "Example of creating a Mix-application - from initialization to publication.",
deps: deps]
end

def package do
[name: :quadratic_equation,
files: ["lib", "mix.exs"],
maintainers: ["Stanislav Gordanov"],
licenses: ["MIT"],
links: %{"Github" => "https://github.com/folklore/quadratic_equation"}]
end

Для публікації вам також буде потрібно профіль на hex.pm. Якщо у вас його ще немає, то найпростіший спосіб його створення, це скористатися командою ...
$ mix hex.user register

Вам знадобиться вказати username, email і пароль. А також підтвердити введений вами email пройшовши по посиланню з відправленого вам листа.
Перед тим як ми до публікації додатки, нам потрібно згенерувати документацію. У разі, якщо ви не досить покрили ваш код описом, нагадую, що модулі документуються за допомогою
@moduledoc
, а функції з допомогою
@doc
.
Ви також можете додати в документацію README файл, для цього включіть його у конфігурацію програми.
# mix.exs

def project do
[#...
docs: [extras: ["README.md"]]
]
end

Для генерації документації використовуйте команду ...
$ mix docs

Коли всі попередні кроки зроблені, можна приступити до публікації додатка в пакетний менеджер. Сама публікація не хитромудра, і проводиться такою командою ...
$ mix hex.publish

Тепер ваше додаток доступний за адресою https://hex.pm/packages/quadratic_equation.
Висновок
Як ви можете бачити генерація скелета додатки з допомогою Mix справа не хитра, так само як і його публікація в менеджер пакетів. Писати свої програми на Elixir не так вже й складно. Вивчайте мову, знаходите ідеї і реалізуйте їх. Вперед!
Література
» Introduction to Mix
» Organising your Elixir project with Mix
» Create a Mix Task for an Elixir Project
» Write and publish your first Elixir library
» Writing and Publishing an Elixir Library
» Creating Elixir libraries as OTP applications
» Elixir With José Valim | Protal
» Quadratic equation
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.