ruby - 在splat之前省略默认参数

时间:2014-01-06 14:19:46

标签: ruby

我有以下方法签名

def invalidate_cache(suffix = '', *args)
  # blah
end

我不知道这是否可行,但我想调用invalidate_cache并有时省略第一个参数,例如:

middleware.invalidate_cache("test:1", "test")

这当然会将第一个参数绑定到后缀,将第二个参数绑定到args。

我希望两个参数都绑定到args而不用这样调用:

middleware.invalidate_cache("", "test:1", "test")

有没有办法解决这个问题?

3 个答案:

答案 0 :(得分:3)

使用关键字参数(这适用于Ruby 2.0 +):

def invalidate_cache(suffix: '', **args) # note the double asterisk
  [suffix, args]
end

> invalidate_cache(foo: "any", bar: 4242)
=> ["", {:foo=>"any", :bar=>4242}]

> invalidate_cache(foo: "any", bar: 4242, suffix: "aaaaa")
=> ["aaaaa", {:foo=>"any", :bar=>4242}]

请注意,您将使用哈希而不是数组中的varargs,并且密钥仅限于有效的符号。

如果您需要按位置引用参数,请使用Hash#values从哈希创建一个数组。

答案 1 :(得分:0)

如何为invalidate_cache创建一个包装方法,只需使用后缀的标准参数调用invalidate_cache

答案 2 :(得分:0)

为了做到这一点,你的代码必须有一些方法来区分后缀和另一个args。例如。在您的第一个示例中,您的程序如何知道您并不意味着"test:1"实际上是后缀?

如果您可以回答该问题,您可以编写一些代码以使该方法在运行时确定您是否提供了后缀。例如,假设您指定所有后缀必须以句点开头(并且不会有其他参数)。然后你可以做这样的事情:

def invalidate_cache(*args)
  suffix = (args.first =~ /^\./) ? args.shift : ''
  [suffix, args]
end

invalidate_cache("test:1", "test") #=> ["", ["test:1", "test"]]
invalidate_cache(".jpeg", "test:1", "test") #=> [".jpeg", ["test:1", "test"]]

但是,如果实际上没有办法区分作为后缀的参数与要与args混淆的参数之间的区别,那么你就会陷入困境。您必须明确地继续传递后缀,更改方法签名以使用关键字参数(详见karatedog's answer),或者使用选项哈希。