Ruby 3.0 - 参数数量错误(给定 3,预期 1..2)

Ris*_*sha 3 ruby validation ruby-on-rails ruby-3

我们有一个正在使用 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 
Run Code Online (Sandbox Code Playgroud)

上面的代码在 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) 
Run Code Online (Sandbox Code Playgroud)

我的 Ruby 和 Rails 知识还不是很丰富,但是在网上搜索了很多内容并尝试了不同的东西之后,我发现更改record.errors.add attribute, :invalid_uk_postcode, options可以record.errors.add attribute, :invalid_uk_postcode, **options修复测试。因此,在最后一个参数中添加 ** 可以修复测试,并且验证似乎可以正常工作。从我到目前为止所读到的内容来看,参数似乎必须更加具体,并且通过添加 ** 使其成为关键字参数(我假设它可以采用任何类型/值),但因为我不是作为 Ruby 和 Rails 方面的专家,这更多的是猜测,而不是正确理解这一点。

有人可以更好地指导吗?通过这种方式修复上述更改似乎可以吗?为什么在最后一个参数中添加 ** 可以修复错误问题?

我不确定自动取款机、选项指的是什么以及我将来会研究的内容,但任何知道并可以回答的人将不胜感激。谢谢

网上搜索了一下错误,可以看到Ruby语法有变化。试图理解这一点。

Dee*_*eep 10

关键字参数现在与位置参数完全分离

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
Run Code Online (Sandbox Code Playgroud)

方法的定义add是:

def add(attribute, type = :invalid, **options)
Run Code Online (Sandbox Code Playgroud)

所以现在不支持在options没有的情况下传递哈希值。**相反,您可以直接将它们作为关键字参数传递,如下所示**

record.errors.add attribute, :invalid_uk_postcode, count: 25, other_attr: 'any text'
Run Code Online (Sandbox Code Playgroud)

详细文章在这里:https://www.ruby-lang.org/en/news/2019/12/12/separation-of-positional-and-keyword-arguments-in-ruby-3-0/