2014-01-06 152 views
0

前省略默认参数有了方法签名红宝石 - 图示

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

我不知道这是可能的,但我想打电话给invalidate_cache有时省略第一个参数,例如以下:

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

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

我想这两个参数被束缚成参数,而无需调用是这样的:

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

是否有办法解决这?

+1

您将如何编码*有时省略第一个参数,例如:*运行时间? –

回答

3

使用关键字参数(这部作品在红宝石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}] 

注意,您将有可变参数的哈希,而不是一个数组和密钥被限制为有效符号。

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

+1

Fyi,关键字参数仅在Ruby v2.0 +中受支持。 – Ajedi32

+0

@ Ajedi32:谢谢,我更新了答案。 – karatedog

0

您如何为invalidate_cache创建一个包装方法,该方法只需将invalidate_cache与后缀的标准参数一起调用即可。

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),要么采用选项哈希。