Techioz Blog

Ruby 3.0 - 引数の数が間違っています (3 が指定され、1..2 が予想されます)

概要

uk_postcode gem を使用するプロジェクトがあります。次のようなバリデータクラスがあります。

class UkPostcodeValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    postcode = UKPostcode.parse(value.to_s)
    return if postcode.full_valid?

    record.errors.add attribute, :invalid_uk_postcode, options
  end
end 

上記は Ruby 2.7.6 では正常に動作していましたが、Ruby 3.0.0 に更新する必要があります。これを実行すると、テストが壊れて次のエラーが発生します。

Failure/Error: record.errors.add attribute, :invalid_uk_postcode, options
     
     ArgumentError:
       wrong number of arguments (given 3, expected 1..2) 

私のRubyとRailsの知識はまだ十分ではありませんが、オンラインでたくさん検索してさまざまなことを試した結果、record.errors.add属性、:invalid_uk_postcode、オプションをrecord.errors.add属性、:invalid_uk_postcode、optionsに変更することがわかりました。テストを修正します。したがって、最後の引数に を追加するとテストが修正され、検証が通常どおり動作するように見えます。これまで読んだことから、引数はより具体的である必要があり、**を追加することでキーワード引数になります(任意の型/値を取ることができると想定しています)が、私は専門家ではないので、 Ruby と Rails の専門家ではありますが、これを正しく理解するというよりは推測にすぎません。

誰かがもっと上手にガイドしてくれるでしょうか?上記の変更はこのように修正しても問題ないと思われますか?最後の引数に ** を追加するとエラーの問題が解決するのはなぜですか?

atm、どのオプションがどのようなことを指しているのか、そして将来的には何かを調べているのかわかりませんが、知っていて答えられる人はよろしくお願いします。ありがとう

オンラインでエラーを検索すると、Ruby の構文に変更があることがわかります。これを理解しようとしています。

解決策

キーワード引数が位置引数から完全に分離されるようになりました。

def new_style(name, **options)
end

new_style('John', {age: 10})
# Ruby 2.6: works
# Ruby 2.7: warns: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call
# Ruby 3.0: ArgumentError (wrong number of arguments (given 2, expected 1))
new_style('John', age: 10)
# => works
h = {age: 10}
new_style('John', **h)
# => works, ** is mandatory

add メソッドの定義は次のとおりです。

def add(attribute, type = :invalid, **options)

したがって、** なしでオプションにハッシュを渡すことは現在サポートされていません。代わりに、次のようにキーワード引数として直接渡すことができます。これが ** の動作です。

record.errors.add attribute, :invalid_uk_postcode, count: 25, other_attr: 'any text'

詳細な記事はこちら: https://www.ruby-lang.org/en/news/2019/12/12/separation-of-positional-and-keyword-arguments-in-ruby-3-0/