53
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Rubyのメソッドの引数でデフォルト式を与える場合は、通常の引数ではなく「キーワード引数」を使おう

Last updated at Posted at 2018-09-21

概要

Ruby のメソッドの引数でデフォルト式を与える場合は、キーワード引数を使いましょう。
キーワード引数を使うことで、デフォルト式によって達成したい目的である、関心の分離が達成され、コードの見通しがよくなります。

def foo(bar = 'baz'); end # 悪い例
def foo(bar: 'baz'); end # 良い例

実際にキチンとした例を見ていきましょう。

悪い例

def hello(from = 'Me', to = 'World')
  puts "#{from}: Hello, #{to}!"
end
hello('Me', 'My World') #=> Me: Hello, My World!
hello('Tom') #=> Tom: Hello, World!

良い例

def hello(from: 'Me', to: 'World')
  puts "#{from}: Hello, #{to}!"
end
hello(to: 'My World') #=> Me: Hello, My World!
hello(from: 'Tom') #=> Tom: Hello, World!

キーワード引数によるメリットを分解すると、以下の2つに分類できます。

  • キーワード引数の場合は、必要な引数だけ指定できる
  • キーワード引数の場合は、実引数の意味が分かりやすい

必要な引数だけ指定できる

概要で例としてあげた hello 関数の呼び出し方に注目してみましょう。
自分が作った My World に対して hello と呼びかけたいことをコードで表現してみましょう

# 悪い例
hello('Me', 'My World')

# 良い例
hello(to: 'My World')

通常の引数を利用した場合は、我々の関心事は、 My World に対して hello したいということであるのに、 Me も指定する必要が出てきています。一体、Me って何のことなのでしょうか?
これでは、関心の分離が出来ていませんね。しかも、メソッド定義を変更した場合にリファクタ

これは、Rubyの仕様上、引数は個数と位置によって識別されている為、逃れられないことです。

一方、キーワード引数を利用した場合は、 My World のみを指定すればよく、関心の分離が達成されています。

実引数の意味が分かりやすい

概要で例としてあげた hello 関数の呼び出し方に注目してみましょう。
TomHello, World! と喋ってもらいたいことをコードで表現してみましょう。

# 悪い例
hello('Tom')

# 良い例
hello(from: 'Tom')

通常の引数の場合は、呼び出し側のコードを見るだけでは、実行される処理が分かりづらいですが、キーワード引数を利用することによって、呼び出し側のコードを見るだけで、何が実行されるかが明確です。

通常の引数では、Tom に対して hello しているのかな? って勘違いしちゃいますよね。
しかし、通常の引数の場合、メソッド定義としては、 from, to という順序で引数を定義するのはごく自然なのです。

どうしてこのような事故が起きてしまうのでしょうか。

まず、一般的に、デフォルト式をもたせるメソッド名は、省略された状態で完全性を担保する必要があります。完全性が担保されるということは、メソッド名にもその完全性は現れます。つまり、 hello_from というような、目的語を取る複合動詞ではなく、hello というような、目的語を取らない複合動詞のメソッド名が選択されます。そして、選択されるべきです。この状態では、動詞たるメソッド名と、目的語たる引数の関係性は、メソッドというI/Fからは失われています。

更に、デフォルト式をもたせるメソッドは、デフォルト式を指定されない状態で呼ばれることが殆どです。それは、開発者がコードを書く時に、デフォルト式はコードの関心の外であるためです。しかし、このような状況が継続した場合、開発者の頭の中からはメソッドの定義は消えています。そう、関心の外になっているからです。当然、メソッド定義を読めば良いということですが、これは開発時(特にコードリーディング時)のオーバーヘッドになるので、コードがキチンと処理を表現する状態が望ましいです。

逆に、キーワード引数を利用した場合には、メソッドと引数の関係が from というキーワードによって明確になるので、メソッド定義に関心を向ける必要がなくなります。また、その関係性が呼び出し側のコードに明示されるため、開発者もメソッド定義まで立ち戻る必要はなくなるのです。

まとめ

通常の引数を使うか、キーワード引数を使うか。
些細な違いが、コードの品質や開発効率に大きな違いを与えてしまうので、デフォルト式としてはキーワード引数を使うことをオススメします。

53
25
0

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
53
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?