iex, mix и первый проект
Прежде чем писать большие системы, освойте два инструмента, в которых проходит вся жизнь Elixir-разработчика: iex — интерактивная оболочка, и mix — сборщик проектов.
В Elixir принято исследовать код вживую: набрал выражение в iex — сразу увидел результат. Это меняет способ мышления о программе.
iex (Interactive Elixir) — это REPL, в котором можно вычислять выражения, подгружать модули, инспектировать процессы и даже подключаться к работающему продакшен-узлу. Запустим:
$ iex
Erlang/OTP 27 [erts-15.0]
Interactive Elixir (1.18.0)
iex(1)> 1 + 2
3
iex(2)> String.length("BEAM")
4
iex(3)> h String.upcase # встроенная справка прямо в оболочке
Реальные проекты собирает mix. Он создаёт скелет, управляет зависимостями, гоняет тесты и компилирует код:
$ mix new my_app
$ cd my_app
$ mix deps.get # подтянуть зависимости из hex
$ mix test # запустить тесты
$ iex -S mix # запустить iex с загруженным проектом
Внутри проекта главное — файл mix.exs с описанием приложения и зависимостей, папка lib/ с кодом и test/ с тестами.
# lib/my_app.ex
defmodule MyApp do
@moduledoc "Точка входа приложения."
def hello(name) do
"Привет, " <> name <> "!"
end
end
Как работает под капотом (BEAM)
Когда вы запускаете iex -S mix, происходит несколько вещей: mix компилирует все .ex файлы в .beam-байткод (кладёт их в _build/), стартует BEAM-узел, загружает скомпилированные модули и приложения в порядке зависимостей, а затем открывает оболочку внутри этого живого узла. Поэтому в iex вам доступны все ваши модули, и можно вызывать функции работающей системы — это не отдельный процесс, а та же VM.
mix new -> скелет (mix.exs, lib/, test/) mix compile -> .ex => .beam (в _build/) iex -S mix -> старт BEAM-узла + загрузка модулей + REPL
Та же идея на Python ▶
В Python тоже есть REPL и менеджер проектов. Конвейер «исходник → готовый к запуску артефакт» можно показать так:
def hello(name):
return "Привет, " + name + "!"
# "REPL-сессия": вычисляем выражения по одному
print(hello("BEAM")) # Привет, BEAM!
print(len("BEAM")) # 4
print("elixir".upper()) # ELIXIR
# mix new ~ python -m venv + pyproject.toml + src/
project = {"name": "my_app", "deps": ["jason", "plug"]}
for dep in project["deps"]:
print("подтягиваю зависимость:", dep)
Частые ошибки
- Путать iex и mix. iex — оболочка, mix — сборщик. Команды mix (
mix test) не работают внутри iex как есть. - Забыть
-S mix. Голыйiexне видит ваш проект; нуженiex -S mix, чтобы загрузить модули. - Редактировать код и ждать, что iex сам обновится. Нужно перекомпилировать:
recompile()в оболочке.
Best practices
- Держите бизнес-логику в
lib/, тесты — вtest/, конфиг — вconfig/. - Используйте
recompile()в iex после правок вместо перезапуска оболочки. - Фиксируйте версии Elixir/Erlang в
.tool-versions— это спасает команду от «у меня работает».
Итог. iex — ваша песочница для экспериментов, mix — каркас реальных проектов. Эти два инструмента сопровождают вас от первого 1 + 2 до подключения к продакшен-узлу. Дальше — типы данных, на которых всё строится.
Рабочий цикл разработчика
На практике день в Elixir выглядит так: вы держите открытым iex -S mix, правите код в редакторе, затем в оболочке набираете recompile() и тут же проверяете функцию вживую — без перезапуска приложения и потери состояния процессов. Это куда быстрее, чем гонять весь набор тестов на каждую мелочь. Когда логика устоялась, вы закрепляете её тестом и запускаете mix test отдельной командой в терминале.
Полезно знать ещё несколько команд mix: mix format приводит код к единому стилю (в Elixir есть официальный форматтер, споров о стиле почти нет), mix deps.get подтягивает зависимости из hex.pm, mix help показывает все доступные задачи, включая те, что добавили библиотеки. Сам mix расширяем: Phoenix добавляет mix phx.server, Ecto — mix ecto.migrate. Освоив этот цикл «правка → recompile → проверка в iex → тест», вы получаете очень короткую петлю обратной связи, ради которой многие и любят язык.