以下代码:
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=>"value", :val2=>"value2"}
这种行为的来源在哪里,我错过了什么或者它是一个错误? Ruby版本2.1.1和2.1.2已经过测试。
答案 0 :(得分:3)
我目前正在使用Ruby 2.1.0p0。
使用以下示例可以简化“问题”:
def foo(arg1 = {}, arg2: 'value1')
[arg1, arg2]
end
此处,方法foo
有一个OPTIONAL参数arg1
(默认为{}
)和一个OPTIONAL关键字参数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
)与唯一的OPTIONAL关键字参数(关键字arg2
)相匹配。它们不匹配,因此错误。
在下一个例子中:
foo({val1: 'value', val2: 'value2'}, arg2: 1)
我们得到了结果:
=> [{:val1=>"value", :val2=>"value2"}, 1]
这是有道理的,因为我提供了两个论点。 Ruby可以将arg2: 1
与第二个关键字参数匹配,并接受{val1: 'value', val2: 'value2'}
作为第一个可选参数的替代。
我不认为上面的行为是错误的。
答案 1 :(得分:2)
显然,参数分辨率与您的预期相反。除了konsolebox&#39;回答,您可以通过使用额外的空哈希调用构造函数来修复它:
Test.new({key1: 'value1'}, {})
答案 2 :(得分:-1)
请这样做:
class Test
attr_reader :args
def initialize(arg1={}, arg2 = 'value2') ## Changed : to =.
@args = [arg1, arg2]
end
end
t = Test.new({key1: 'value1'})
puts t.args.inspect
输出:
[{:key1=>"value1"}, "value2"]