DEV Community

Seizan Shimazaki
Seizan Shimazaki

Posted on

11 2

Elixirのコードレビューで出るやつ

Elixir Advent Calendar 2016 の12日目です。

Elixir で開発していてコードレビューの指摘点で出たものについて、
一般的だと思うものをいくつか列挙しました。

返り値を想定している場合は _ でマッチさせず名前付ける

名前付けておいた方が読んだときにわかる。

関数定義でマッチできるならそっちで

def spam(x) do
  case x do
    :aaa ->
      :ok
    :bbb ->
      :error
  end
end
Enter fullscreen mode Exit fullscreen mode

のようにやるなら、次のようにする。

def spam(:aaa) do
  :ok
end
def spam(:bbb) do
  :error
end
Enter fullscreen mode Exit fullscreen mode

if より case を使う

場合分けで if を使うことは多くない。
case を使う方が良い場合が多い。

user = Repo.get(query, id)
if user != nil do
  ...
else
  ...
end
Enter fullscreen mode Exit fullscreen mode

と書くなら次のようにする。

case Repo.get(query, id) do
  nil ->
    ...
  user ->
    ...
end
Enter fullscreen mode Exit fullscreen mode

エラー返り値の形式が違うものは with でまとめず case ネストで

with {:ok, foo} <- spam(),
     {:ok, bar} <- ham() do
  ...
else
  :error ->
    ...
  {:error, reason} ->
    ...
end
Enter fullscreen mode Exit fullscreen mode

のように spam() は :error、ham() は {:error, reason} を返すような場合、
with でまとめるとどれがどのエラー形式を返すかわからなくなってつらい。
ので普通に case ネストで書く。

case spam() do
  {:ok, foo} ->
    case ham() do
      {:ok, bar} ->
        ...
      {:error, reason} ->
        ...
    end
  :error ->
    ...
end
Enter fullscreen mode Exit fullscreen mode

関数呼び出しはカッコ省略せず必ず () 付ける

統一するメリットがあるので。

再代入しない

再代入するなら基本的に別の名前を付ける。
Phoenix の conn のようなごく一部の例外は除く。
再代入の必要性は今のところ特に感じていない。

%URI{} 使おう

url_base = "https://#{host}"
url = "#{url_base}/user/#{user_id}"
Enter fullscreen mode Exit fullscreen mode

とかやるなら URI を使う。(HTTPoison など URI 型で渡せる)

url = %URI{scheme: "https",
           host: host,
           path: Path.join("/user", user_id)}
Enter fullscreen mode Exit fullscreen mode

String にしたければ URI.to_string() を使えばよい。

条件を満たすならリストに追加する

List や Map を作るときに条件を満たす場合は追加することがある。
例えばこんな感じ。

@spec build_spams() :: list()
def build_spams() do
  spams = base_spams()
  spams = if condition1() do
    [additional1() | spams]
  else
    spams
  end
  spams = if condition2() do
    [additional2() | spams]
  else
    spams
  end
  spams
end
Enter fullscreen mode Exit fullscreen mode

要素追加する部分を関数に切り出すと見通しがよくなる場合がある。
以下のような感じ。

@spec build_spams() :: list()
def build_spams() do
  base_spams()
  |> maybe_add_spams1()
  |> maybe_add_spams2()
end

defp maybe_add_spams1() do
  if condition1() do
    [additional1() | spams]
  else
    spams
  end
end

defp maybe_add_spams2() do
  if condition2() do
    [additional2() | spams]
  else
    spams
  end
end
Enter fullscreen mode Exit fullscreen mode

おまけ: credo

CI で mix credo は必ず回すようにしている。
.credo.exs は次の感じでやってる。

%{
  configs: [
    %{
      name: "default",
      files: %{
        included: ["lib/"],
        excluded: []
      },
      checks: [
        {Credo.Check.Readability.MaxLineLength, max_length: 120},
        {Credo.Check.Readability.ModuleDoc, false},
        {Credo.Check.Refactor.Nesting, false},
        {Credo.Check.Refactor.PipeChainStart, false},
      ]
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Heroku

Deploy with ease. Manage efficiently. Scale faster.

Leave the infrastructure headaches to us, while you focus on pushing boundaries, realizing your vision, and making a lasting impression on your users.

Get Started

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay