Techioz Blog

Ruby 3.2 - 単一の引数に関するキーワード引数の問題

概要

古いコード ベースを調べていると、単一のキーワード引数を持つメソッド シグネチャの例を確認できます。

これは Ruby で通常行うことですか?ちょっと奇妙に思えます。 1 つ以上の引数を指定できる場所でこれが使用されることを期待しています。

Ruby 3.2 のアップグレードで、テスト スイートの実行時にこの構文が崩れることに気付きました。

これは Ruby 3.2 で削除されたものですか。ドキュメントを確認しましたが、問題を特定できません。

def greet(name: "Guest")
  puts "Hello, #{name}!"
end

greet(name: "Alice")  # Output: Hello, Alice!

解決策

それはユースケースによって異なります。引数が 1 つであっても、キーワード引数は引数の意図をより明確に伝えるのに役立ちます。 obj.clone(freeze: false) または Time.now(in: ‘+0200’)。

名前がないと、引数が何をするのかが明確になりません: obj.clone(false)

あなたの場合、リッチ ユーザー オブジェクトや挨拶メッセージなどの代わりに名前を渡すヒントになる可能性があります。あるいは、作成者がコードをより明示的にしたかっただけかもしれません。

あなたが示した例は Ruby 3.2 で完全に有効であり、エラーは発生しません。 Ruby 3.x の大きな変更点の 1 つは、暗黙的なハッシュからキーワード引数への変換が削除されたことです。

hash = { name: "Alice" }

greet(hash)
# Ruby 2.6: works
# Ruby 2.7: works but prints deprecation warning (when enabled)
# Ruby 3.x: raises ArgumentError

古いコード ベースに上記のようなものがある場合は、ここで ** を追加して、ハッシュをキーワード引数に明示的に変換する必要があります。

greet(**hash)