9
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ElixirAdvent Calendar 2023

Day 23

【Elixir アンチパターン】 関数定義の作法

Last updated at Posted at 2023-12-22

引き続き、Elixir アンチパターンを読んでみます。

今日は、unrelated-multi-clause-functionです。

Elixirでは同じ関数名の関数を定義して、パターンマッチでマッチどれが実行されるか選択する事ができます。
このアンチパターンの例は、update という名前の関数だけど、引き数がProductだったら、Productの更新をして、Animalだったら、Animalの更新をするというものです。

@doc """
Updates a struct.

If given a "sharp" product (metal or glass with empty count),
it will...

If given a blunt product, it will...

If given an animal, it will...
"""
def update(%Product{count: nil, material: material})
    when material in ["metal", "glass"] do
  # ...
end

def update(%Product{count: count, material: material})
    when count > 0 and material not in ["metal", "glass"] do
  # ...
end

def update(%Animal{count: 1, skin: skin})
    when skin in ["fur", "hairy"] do
  # ...
end

こんな事する奴いないだろう。という例なんですが、知らず知らずのうちにやってるかもしれないです。

お勧めのコードは、update_sharp_product/1とupdate_animal/1の二つの関数に分ける事です。

@doc """
Updates a "sharp" product.

It will...
"""
def update_sharp_product(%Product{count: nil, material: material})
    when material in ["metal", "glass"] do
  # ...
end

@doc """
Updates a "blunt" product.

It will...
"""
def update_blunt_product(%Product{count: count, material: material})
    when count > 0 and material not in ["metal", "glass"] do
  # ...
end

@doc """
Updates an animal.

It will...
"""
def update_animal(%Animal{count: 1, skin: skin})
    when skin in ["fur", "hairy"] do
  # ...
end

updateという名前から、更新するものは何でもupdateにまとめよう。と思ったのかもしれませんが、何を更新するのかが、関数名を見ただけではわからないものになってしまっています。
関数にはわかりやすい名前をつけましょう。

関数名の大切さはいろいろ語られてますが、クリーンコードという本、お勧めです。

9
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?