【Ruby】なんでもかんでもキーワード引数にしない

## はじめに:そのキーワード引数、いる? コードレビューでよく指摘しているシリーズです。 コードレビューをしていると、ときどきこういうコードに出会います。 ```ruby # うーん🤔 def say_hello_to(name:) "Hello, #{name}!" end say_hello_to(name: 'Alice') ``` そのキーワード引数……いりますかね? これでよくないですか? ```ruby # good👍 def say_hello_to(name) "Hello, #{name}!" end say_hello_to('Alice') ``` キーワード引数を使うよりもシンプルですし、コードの可読性も落ちていないと思います。 ## 原則:まずは普通の引数にする メソッドを定義するときはまず、普通の引数で定義するようにしましょう。 最初からキーワード引数にしようとしないでください。 その上で、「これはふつうの引数だと都合が悪い」と考えたときにキーワード引数の導入を検討してください。 ## キーワード引数が有効なケース 普通の引数よりもキーワード引数にした方がよいケースを以下で紹介します。 ### true/falseのままだとわかりにくい場合 たとえば、次のようなコードがあったとします。 ```ruby say_hello_to('ありす', true) ``` 第1引数の"ありす"はおそらくあいさつする相手の名前っぽいですが、第2引数のtrueは何を意味するんでしょうか?ちょっとこれだと予想がしづらいですよね。 では、次のようになっていたらどうでしょう? ```ruby say_hello_to('ありす', in_japanese: true) ``` `:in_japanese`がtrue、ということは「日本語であいさつする」引数なのかもしれない、と予想が付きますよね! ```ruby def say_hello_to(name, in_japanese: false) if in_japanese "こんにちは、#{name}さん!" else "Hello, #{name}!" end end ``` このように普通の引数だとコードの可読性があまりよくない(引数の意味がわかりづらい)ときにキーワード引数を導入すると、コードの可読性が向上する場合があります。 ### コラム:キーワード引数が使えない場合は説明変数を導入する 上の例では `say_hello_to` メソッドの定義を変更してキーワード引数を使えるようにしましたが、これが外部ライブラリのメソッドだったりすると定義を変更することができません。 こういう場合は説明変数を導入することでコードの可読性を上げることができます。 ```ruby # 説明変数なし say_hello_to('ありす', true) # 説明変数あり in_japanese = true say_hello_to('ありす', in_japanese) ``` 説明変数を導入すると変数を定義するぶん、コードの行数は増えますが、それと引き換えにコードの可読性(わかりやすさ)がアップしています。 ## オプションとして指定可能な引数を複数個用意する場合 たとえば以下のように「円を描く」メソッドがあったとします。 ```ruby # 引数はそれぞれ、サイズ、線の太さ(デフォルトは1)、線の色(デフォルトは黒)を示す def draw_circle(size, border_width = 1, border_color = "#000000") # 実装は省略 end ``` サイズ、線の太さ、線の色をすべて指定したいときは、以下のようにメソッドを呼び出します。 ```ruby draw_circle(10, 3, '#188CFF') ``` 線の太さは指定するが、線の色はデフォルトのままで良い、というときは以下のように呼び出せます。 ```ruby # 線の太さは3、線の色はデフォルトの黒(デフォルト値でいいので省略) draw_circle(10, 3) ``` しかし、線の色は指定するが、線の太さはデフォルトのままでよい、というときが困ります。 線の色は第3引数なので、線の太さはデフォルトで良いと思っても、必ず第2引数を指定しなければなりません。 ```ruby # 線の太さはデフォルトの1でいいが、第2引数なので省略できない draw_circle(10, 1, '#188CFF') ``` こういう場合にキーワード引数を活用すると便利です。 ```ruby def draw_circle(size, border_width: 1, border_color: "#000000") # 実装は省略 end ``` 線の色だけ指定したい場合は次のように書けます。 ```ruby # 線の色だけ指定する(線の太さはデフォルトの1) draw_circle(10, border_color: '#188CFF') ``` もちろん、線の太さだけ指定したり、両方指定したりすることも可能です。 ```ruby draw_circle(10, border_width: 3) draw_circle(10, border_width: 3, border_color: '#188CFF') ``` このように「デフォルト値は予め決まっているが、引数で自由に指定可能」というメソッドを定義したい場合はキーワード引数を有効活用できます。 他にもまだキーワード引数が有効な場面はあるかもしれませんが、とりあえず代表的なユースケースとして上の2つを紹介してみました。 ## まとめ というわけでこの記事ではメソッド定義する場合に、キーワード引数にするかどうかをきちんと見極めましょう、という話を書いてみました。 原則は「キーワード引数にせず、普通の引数として定義する」です。 その上で、「これは普通の引数だと可読性が低かったり、不便だったりするのでは?」と感じたときにキーワード引数を導入するようにしてください!