less than 1 minute read

list를 인자로 받는 함수가 있을 때, list로 가공해서 넘겨야 한다.

a = :some_element
if is_list(a), do: a, else: [a]
[:some_element]

이렇게 짤 수 있는데, 이러면 nil 일 때, 의도한 것과 다르게 동작한다.

a = nil
if is_list(a), do: a, else: [a]
[nil]

비어있는 list를 기대하지만 [nil] 을 리턴한다.

a = nil
case a do
  nil -> []
  a when is_list(a) -> a
  _ -> [a]
end
[]

이제 nil이면 빈 리스트를 리턴한다.

List.wrap(:a) |> IO.inspect
List.wrap([:a, :b]) |> IO.inspect
List.wrap(nil) |> IO.inspect
:ok
[:a]
[:a, :b]
[]
:ok

이렇게 할 필요없이 elixir 표준 라이브러리에 있는 List.wrap/1 함수를 사용하면 된다.

defmodule List do
  # ...
  @spec wrap(term) :: maybe_improper_list()
  def wrap(term)

  def wrap(list) when is_list(list) do
    list
  end

  def wrap(nil) do
    []
  end

  def wrap(other) do
    [other]
  end
  # ...
end

간단한 패턴 매칭으로 구현했다.

~를 싸다, 포장하다는 wrap을 사용한 네이밍이 마음에 든다.