处理带有可选参数和关键字参数列表的方法

时间:2019-01-10 13:44:38

标签: ruby arguments splat

我想将可选参数(任何数据类型,甚至是哈希)传递给方法,然后将关键字参数列表(可以为空)传递给方法。

这就是我得到的:

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'})吗?关于如何获得理想结果的任何想法?

3 个答案:

答案 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'}, {})