Code Fix

中級

必須キーワード引数を渡し忘れると ArgumentError になる

デフォルト値の無いキーワード引数(name: のようにコロンだけで値を書かない形)は必須です。呼び出し時に渡し忘れると、通常の引数と同じくArgumentErrorになります。

エラーメッセージの読み方

main.rb:1:in `create_user': missing keyword: :age (ArgumentError)
main.rb
ファイル名
1
行番号 — 実際にクラッシュした行
create_user
発生場所 — <main> ならトップレベル、メソッド名ならそのメソッドの中
ArgumentError
例外クラス — 何が起きたか。ここを検索するのが最短です
missing keyword: :age
詳細メッセージ — どの値が問題だったか

このエラーが出る典型パターン

パターン1

 1  def create_user(name:, age:)
 2    "#{name} (#{age})"
 3  end
 4  puts create_user(name: "Taro"         )
                                     ^
main.rb:1:in `create_user': missing keyword: :age (ArgumentError) from main.rb:4:in `<main>'

デフォルト値の無いキーワード引数は必須です。渡し忘れると通常の引数と同じくArgumentErrorになります。

直し方: (空) を , age: 20 にします。

この問題を解いてみる →

広告
広告スロット(未設定)

パターン2

 1  def book_room(room:, nights:)
 2    "#{room} for #{nights} nights"
 3  end
 4  puts book_room(room: "101"           )
                                   ^
main.rb:1:in `book_room': missing keyword: :nights (ArgumentError) from main.rb:4:in `<main>'

名前付きだからといって省略できるわけではありません。省略可能なのはデフォルト値を明示した引数だけです。

直し方: (空) を , nights: 3 にします。

この問題を解いてみる →

パターン3

 1  def register(email:, plan:)
 2    "#{email} - #{plan}"
 3  end
 4  puts register(email: "a@b.com"             )
                                        ^
main.rb:1:in `register': missing keyword: :plan (ArgumentError) from main.rb:4:in `<main>'

どのキーワードが足りないかはエラーメッセージにそのまま表示されます。

直し方: (空) を , plan: "pro" にします。

この問題を解いてみる →

パターン4

 1  def schedule(date:, time:)
 2    "#{date} #{time}"
 3  end
 4  puts schedule(date: "8/28"               )
                                     ^
main.rb:1:in `schedule': missing keyword: :time (ArgumentError) from main.rb:4:in `<main>'

必須キーワード引数はコロンだけでデフォルト値を書かない形で宣言されます。

直し方: (空) を , time: "10:00" にします。

この問題を解いてみる →

パターン5

 1  def order(item:, qty:)
 2    "#{item} x#{qty}"
 3  end
 4  puts order(item: "pen"        )
                              ^
main.rb:1:in `order': missing keyword: :qty (ArgumentError) from main.rb:4:in `<main>'

呼び出し時にすべての必須キーワード引数を渡しているか、定義と見比べて確認する必要があります。

直し方: (空) を , qty: 5 にします。

この問題を解いてみる →

よくある誤解

「キーワード引数は名前付きだから省略できるはず」という思い込みは誤りです。デフォルト値を明示的に指定した引数だけが省略可能で、指定していないキーワード引数は普通の引数と同じく必須です。

実務での勘所

キーワード引数の扱いは、Ruby 2.7から3.0にかけて大きく変更された経緯があります。それ以前は、末尾のハッシュ引数とキーワード引数が曖昧に相互変換されることがあり、意図しない挙動の原因になっていました。Ruby 3.0では、位置引数としてのハッシュとキーワード引数が明確に別物として分離され、暗黙の変換は基本的に行われなくなりました。古い書籍やネット上の情報がRuby 2.6以前を前提にしている場合、キーワード引数まわりの挙動の説明が現在のRubyと食い違っていることがあります。

演習をはじめる

関連するエラー

広告
広告スロット(未設定)