Ruby 在关键字参数与位置混合中的奇怪行为

标签 ruby ruby-2.1 keyword-argument

以下代码:

class Test
  attr_reader :args
  def initialize(arg1={}, arg2: 'value2')
    @args = [arg1, arg2]
  end
end
t = Test.new({key1: 'value1'})
puts t.args

我期望打印出包含内容的数组[{key1: 'value1'}, 'value2'] 但我得到:

test.rb:11:in `new': unknown keywords: val1, val2 (ArgumentError)
    from test.rb:11:in `<main>'

更奇怪的是,使用 {val1: 'value', val2: 'value2'}, arg2: 1) 作为参数调用相同的测试类,我得到输出:{:val1=>"值", :val2=>"值2"}

这种行为的根源在哪里,我遗漏了一些东西还是它是一个错误? 已测试 Ruby 版本 2.1.1 和 2.1.2。

最佳答案

我目前使用的是 Ruby 2.1.0p0。

可以通过以下示例稍微简化“问题”:

def foo(arg1 = {}, arg2: 'value1')
  [arg1, arg2]
end

此处,方法 foo 有一个可选参数 arg1(默认为 {})和一个可选关键字参数 arg2 .

如果您调用:

foo({key1: 'value1'})

您收到错误:

ArgumentError: unknown keyword: key1
        from (irb):17
        from /home/mark/.rvm/rubies/ruby-2.1.0/bin/irb:11:in `<main>'

原因是 Ruby 试图将您提供的唯一参数(使用关键字 key1)与唯一的可选关键字参数(关键字 arg2)进行匹配。它们不匹配,因此出现错误。

在下一个示例中:

foo({val1: 'value', val2: 'value2'}, arg2: 1)

我们得到结果:

=> [{:val1=>"value", :val2=>"value2"}, 1]

这是有道理的,因为我提供了两个参数。 Ruby 可以将 arg2: 1 与第二个关键字参数匹配,并接受 {val1: 'value', val2: 'value2'} 作为第一个可选参数的替代。

我不认为上述行为是错误。

关于Ruby 在关键字参数与位置混合中的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25390181/

相关文章:

Ruby - Digest::Digest 已弃用;使用摘要

python - 通过多级函数传递 kwargs,解包其中一些但传递所有函数

Ruby 关键字参数说明

ruby - failedPrecondition : Must be a G Suite domain user. 使用服务帐户管理 ruby​​ 中的联系人

yaml - 修复 : Prior to 0. 1.6,libyaml 容易受到恶意 YAML 负载的堆溢出攻击

ruby - 为什么 `rvm install ruby-2.1.0` 会安装 preview1?

python - Django View 中的 args 和 kwargs

objective-c - NSJSONSerialization.JSONObjectWithData 浮点转换/舍入错误?

ruby - 是否可以动态创建页面对象元素

mysql - RAILS ActiveRecord::Relation 如何获取多对多:表名