【发布时间】:2017-12-14 12:56:07
【问题描述】:
在 Ruby 2.4.1 中,我有一个这样的方法:
def example(*args, **kwargs)
p args
p kwargs
end
我可以传入不是哈希的位置参数就好了:
irb(main):001:0> example("Greetings")
["Greetings"]
{}
如果我想使用命名参数,那也没关系:
irb(main):002:0> example(something: 42)
[]
{:something=>42}
但是尝试将 Hash 作为位置参数传递时,会发生这种情况:
irb(main):002:0> example({something: 42})
[]
{:something=>42}
我希望*args 使用{something: 42},而不是**kwargs。
位置参数必须是可选的,但即使 *args 是 arg=nil,双 splat 仍然太贪心:
irb(main):001:0> def example(arg=nil, **kwargs)
irb(main):002:1> p arg
irb(main):003:1> p kwargs
irb(main):004:1> end
=> :example
irb(main):005:0> example({"key":"value"})
nil
{:key=>"value"}
irb(main):006:0> example({"key":"value"}, this_is: "in kwargs")
{:key=>"value"}
{:this_is=>"in kwargs"}
当方法也采用 ** 时,我如何将 Hash 作为位置参数传递?
【问题讨论】:
-
这会使 API 变得非常混乱。将哈希作为位置参数传入并同时具有哈希样式选项的动机是什么?为什么不能用特定的参数声明它,比如
example(arg = nil, option: false, other: true)? -
@tadman:我希望第一个位置参数可以是一个字符串值的哈希值,作为有效负载转换为 JSON,这样客户端代码就不必调用
.to_json。命名参数将是进入RestClient::Resource选项的选项,它可以采用许多不同的选项,所以我觉得接受所有可能性而不是挑选其中的许多来传递会更简单。 -
如果您传递字符串键而不是符号键,它将显示在 *args 中。 Kwargs 仅适用于符号键。
-
@RadaBogdan:在
irb中运行example({"having spaces": "works?"}),你会看到**kwargs仍然会吃掉争论。
标签: ruby methods parameter-passing ruby-hash double-splat