以下代码:
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/