Перейти к основному содержимому

Простые приложения на Elixir

Разработчику Архитектору

Простые приложения на Elixir

Elixir работает на BEAM: устойчивые процессы, |> (pipe), pattern matching. Скрипты запускают через elixir script.exs; для HTTP позже — Phoenix, для старта — Plug или :httpc.

Как запускать примеры из главы

  1. Скрипт: elixir имя.exs
  2. Mix-проект: mix run или iex -S mix
  3. Нужно: Elixir 1.14+ (elixir -v).

Генератор паролей

Как запустить

  • Файл: password.exs
  • Команда: elixir password.exs
  • Результат: пароль в stdout.
defmodule Password do
@chars ~c"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%"

def generate(len \\ 16) do
for _ <- 1..len, into: "", do: <<Enum.random(@chars)>>
end
end

IO.puts(Password.generate())

Сортировщик файла

defmodule SortFile do
def run(input, output) do
lines =
input
|> File.read!()
|> String.split("\n", trim: true)
|> Enum.sort()

File.write!(output, Enum.join(lines, "\n") <> "\n")
end
end

Калькулятор с pattern matching

defmodule Calc do
def eval(a, b, op) when is_number(a) and is_number(b) do
case op do
"+" -> {:ok, a + b}
"-" -> {:ok, a - b}
"*" -> {:ok, a * b}
"/" when b != 0 -> {:ok, a / b}
"/" -> {:error, :div_zero}
_ -> {:error, :bad_op}
end
end
end

Трекер задач (Jason)

# mix.exs — {:jason, "~> 1.4"}
defmodule Tasks do
defstruct [:id, :title, :done]

def load(path) do
case File.read(path) do
{:ok, bin} -> Jason.decode!(bin, keys: :atoms)
{:error, _} -> []
end
end

def save(path, tasks), do: File.write!(path, Jason.encode!(tasks, pretty: true))
end

Простой HTTP (Plug.Cowboy)

# mix.exs — {:plug_cowboy, "~> 2.7"}, {:jason, "~> 1.4"}
defmodule HelloPlug do
use Plug.Router

plug :match
plug :dispatch

get "/" do
send_resp(conn, 200, Jason.encode!(%{ok: true}))
end

match _ do
send_resp(conn, 404, "not found")
end
end

# Plug.Cowboy.http(HelloPlug, [], port — 4000)

Характерный пример — pipe и процессы

defmodule Counter do
def start, do: spawn(fn -> loop(0) end)

defp loop(n) do
receive do
:inc -> loop(n + 1)
{:get, pid} -> send(pid, n); loop(n)
end
end
end

pid = Counter.start()
send(pid, :inc)
send(pid, {:get, self()})
receive do: n when is_integer(n) -> IO.inspect(n)

Процессы изолированы; обмен сообщениями — основа OTP.


См. также: Phoenix и экосистема в разделе Elixir

См. также

Другие статьи этого же раздела в боковом меню (как на странице «О разделе»).