Только что вышел Эликсир 1.14. Узнайте, что нового и, что более важно, почему это важно.

Эликсир 1.14 уже вышел и содержит несколько замечательных улучшений и без того удивительного языка. Несмотря на множество изменений, одна из тем, которая появляется чаще всего, связана с проверкой и отладкой — некоторые полезные изменения, направленные на улучшение процесса разработки и отладки.

В этой статье мы рассмотрим, что нового в версии 1.14, и, что более важно, почему эти изменения важны. Здесь мы сосредоточимся на более крупных и важных изменениях, но под капотом есть масса других изменений, исправлений и улучшений. Полный список изменений смотрите в Журнале изменений Эликсира.

Улучшенная отладка с помощью Kernel.dbg/2.

Регистрация и проверка вывода — распространенный метод отладки для Elixir, особенно в приложениях с высокой степенью параллельности, где традиционные методы отладки, такие как точки останова, могут быть затруднены в использовании. Часто это связано с использованием IO.inspect/2, которое печатает «проверенное» представление значения. Новый Kernel.dbg/2 обеспечивает улучшенную функциональность отладки, добавляя дополнительный контекст по сравнению с тем, что было бы предоставлено IO.inspect/2 .

Давайте посмотрим на пример, представленный в журнале изменений. Вот как может выглядеть код, вызывающий dbg:

# In my_file.exs
feature = %{name: :dbg, inspiration: "Rust"}
dbg(feature)
dbg(Map.put(feature, :in_version, "1.14.0"))

И вот что мы увидим при выполнении кода:

$ elixir my_file.exs
[my_file.exs:2: (file)]
feature #=> %{inspiration: "Rust", name: :dbg}

[my_file.exs:3: (file)]
Map.put(feature, :in_version, "1.14.0") #=> %{in_version: "1.14.0", inspiration: "Rust", name: :dbg}

Помимо улучшенного вывода отладки, Kernel.dbg также предоставляет настраиваемую точку интеграции для других инструментов: например, IEx интегрируется с dbg для обеспечения поведения точки останова, чтобы вы могли проверять состояние приложения при работе с IEx.

Почему это важно

Отладка может быть непростой темой для Elixir, так как инструменты и опыт, как правило, отстают от других популярных языков. Внедрение Kernel.dbg не полностью устраняет недостатки, но является долгожданным дополнением и шагом в правильном направлении. Он одновременно расширяет существующие подходы к отладке вывода (часто реализуемые с помощью IO.inspect, IO.puts) и позволяет использовать более продвинутые подходы, предоставляя точку интеграции для других инструментов.

Улучшенный вывод IO.inspect: проверка на основе выражений

Дополнением к новой функциональности Kernel.dbg/2 являются улучшения самого IO.inspect/2. Используя пример из журнала изменений, давайте посмотрим на предыдущее поведение inspect:

iex(1)> [:apple, :banana]
[:apple, :banana]
iex(2)> MapSet.new([:apple, :banana])
#MapSet<[:apple, :banana]>

В приведенном выше примере мы видим, что наше выражение списка дает правильное представление кода Elixir, которое мы можем скопировать и вставить, но наше выражение MapSet этого не делает!

С изменениями в 1.14 внутренние структуры, такие как MapSet, теперь производят вывод inspect, который является действительным кодом Elixir:

iex(1)> MapSet.new([:apple, :banana]) |> MapSet.put(:pear)
MapSet.new([:apple, :banana, :pear])

Почему это важно

REPL Elixir — неоценимая часть процесса разработки Elixir, а проверка ценности — часть каждого шага оценки. Возможность копировать и вставлять входные и выходные значения из выражений является важной частью цикла REPL, и до версии 1.14 это иногда усложнялось выходом, который не был допустимым кодом Elixir. Это изменение будет приятным дополнением для всех, кто работает с консолью Elixir.

Новый тип супервизора: PartitionSupervisor

В Elixir 1.14 представлен новый PartitionSupervisor, который можно использовать для наблюдения за несколькими идентичными процессами (по умолчанию равными количеству ядер), которые затем могут направлять запросы отдельно через какой-либо ключ раздела по вашему выбору. Этот новый супервизор обеспечивает простую форму параллелизма и балансировки нагрузки для любого процесса.

Давайте быстро взглянем на пример из примечаний к выпуску:

partitioning_key = self()
ErrorReporter.report({:via, PartitionSupervisor, {Reporters, partitioning_key}}, error)

В этом примере модуль ErrorReporter распределяет нагрузку между несколькими процессами Reporter с помощью PartitionSupervisor. Предоставленный partitioning_key указывает, какой процесс следует использовать — с помощью self() в этом примере вызывающий гарантирует, что отдельный процесс всегда использует один и тот же генератор отчетов, но вы можете легко разделить его по какому-либо другому значению, например, идентификатору пользователя или имени хоста.

Почему это важно

PartitionSupervisor помогает как быстрое решение для общего узкого места в производительности: один процесс-потребитель перегружен запросами. Одна из самых сильных сторон Elixir заключается в том, что он построен на Erlang/OTP и имеет действительно потрясающую поддержку параллелизма прямо из коробки. Такие дополнения, как PartitionSupervisor, помогают еще больше расширить эту поддержку.

Резюме — Эликсир 1.14

Elixir — отличный язык программирования, который постоянно совершенствуется. Хотя обновление 1.14 не является революционным, оно содержит ряд важных эргономических улучшений, облегчающих работу. Для получения дополнительной информации об Elixir 1.14, в том числе об установке или обновлении, см. Страница установки Elixir.

Джонатан имеет более чем 20-летний опыт инженерного руководства в больших и малых стартапах. Если вам понравилась эта статья, пожалуйста, подумайте о том, чтобы оставить Джонатану чаевые!