我想将可选参数(任何数据类型,甚至是哈希)传递给方法,然后将关键字参数列表(可以为空)传递给方法。
这就是我得到的:
def my_method(subject = nil, **options)
[subject, options]
end
在以下情况下,方法输出是预期的:
一无所有
my_method()
# => [nil, {}]
一个主题
my_method('foo')
# => ["foo", {}]
带有选项的文字主题
my_method('foo', bar: 'bar')
# => ["foo", {:bar=>"bar"}]
一个Hash
作为带有选项的主题
my_method({foo: 'foo'}, bar: 'bar')
# => [{:foo=>"foo"}, {:bar=>"bar"}]
没有主题,只有选项
my_method(bar: 'bar')
# => [nil, {:bar=>"bar"}]
通过Hash
作为主题且没有其他选择时,期望的结果是:
my_method({foo: 'foo'})
# => [{:foo=>"foo"}, {}]
但是我得到以下信息;我没有正确的主题:
my_method({foo: 'foo'})
# => [nil, {:foo=>"foo"}]
my_method(foo: 'foo')
等于my_method({foo: 'foo'})
吗?关于如何获得理想结果的任何想法?
答案 0 :(得分:3)
请参见,您使用**options
作为参数,没有任何默认值,第一个参数具有默认值。因此,请理解以下单个参数情况,
无论何时传递单个参数,都会尝试将其分配给第二个参数(因为第一个保留默认nil),并且如果由于类型不匹配而失败,则将其分配给第一个参数。 my_method(4)
就是这样工作的。
现在,假设您将单个参数作为哈希传递,将其匹配以分配给第二个参数,然后将其分配给第二个参数,并且第一个参数设置为默认nil。
如果要使其正常运行,则可以执行以下操作
> my_method({sd: 4}, {})
=> [{:sd=>4}, {}]
或者您可以在传递时提供参数名称,
> my_method(subject: {sd: 4})
=> [{:sd=>4}, {}]
答案 1 :(得分:1)
据我所知,这是Ruby传递参数的限制。无法分辨repeat()
和my_method({foo: 'foo'})
为什么不这么做呢?
my_method(foo: 'foo')
这假设if subject.is_a?(Hash) && options.empty?
subject, options = nil, subject
end
不应是哈希值。
答案 2 :(得分:0)
也许不是最佳答案,但是您可以尝试使用keyword argument:
def my_method(subject: nil, **options)
[ subject, options ]
end
然后
my_method(subject: {foo: 'foo'})
=> [{:foo=>"foo"}, {}]
您可以使用
my_method({foo: 'foo'}, {})