Pull to refresh

Добавление to_string упрощает разработку и дебаг кода на Elixir'е

Reading time 2 min
Views 2.6K
Проверим на примере: пишем сервис с аэропортами и направлениями.

defmodule Airport do
  defstruct [:id, :name]
end

defmodule Direction do
  defstruct [:origin, :destination]

  def example do
    madrid = %Airport{id: "MAD", name: "Madrid"}
    riga = %Airport{id: "RIX", name: "Riga"}
    %Direction{origin: riga, destination: madrid}
  end
end

Пока что всё в порядке. Отлично, съели печеньку, смотрим, что дальше в джире. Список самых популярных направлений?



Для начала делаем небольшой тестовый список и получаем нечитаемую простыню:

popular = Enum.map(1..5, fn _ -> Direction.example end)
# =>
# [%Direction{destination: %Airport{id: "MAD", name: "Madrid"},
#   origin: %Airport{id: "RIX", name: "Riga"}},
#  %Direction{destination: %Airport{id: "MAD", name: "Madrid"},
#   origin: %Airport{id: "RIX", name: "Riga"}},
#  %Direction{destination: %Airport{id: "MAD", name: "Madrid"},
#   origin: %Airport{id: "RIX", name: "Riga"}},
#  %Direction{destination: %Airport{id: "MAD", name: "Madrid"},
#   origin: %Airport{id: "RIX", name: "Riga"}},
#  %Direction{destination: %Airport{id: "MAD", name: "Madrid"},
#   origin: %Airport{id: "RIX", name: "Riga"}}]

Добавляем щепотку читаемости:

defimpl String.Chars, for: Airport do
  def to_string(airport) do
    "#{airport.name} (#{airport.id})"
  end
end

defimpl String.Chars, for: Direction do
  def to_string(direction) do
    "#{direction.origin} → #{direction.destination}"
  end
end

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

Enum.each(popular, fn(x) -> IO.puts(x) end)  
# =>
# Riga (RIX) → Madrid (MAD)
# Riga (RIX) → Madrid (MAD)
# Riga (RIX) → Madrid (MAD)
# Riga (RIX) → Madrid (MAD)
# Riga (RIX) → Madrid (MAD)

А теперь серьёзно


Иногда при разработке нужно анализировать содержимое переменных. Внутреннее представление точное, но не всегда читаемое. В таких случаях можно научить Elixir переводить ваши структуры в строки. Для этого определите функцию to_string в рамках реализации протокола String.Chars.

В качестве дополнительного бонуса автоматом начнёт работать интерполяция. Без реализации to_string для аэропортов такое бы не сработало:

"#{direction.origin} → #{direction.destination}"

На этом всё. Читаемого кода!
Tags:
Hubs:
+5
Comments 7
Comments Comments 7

Articles