Ruby double splat 参数对于 Hash 参数来说太贪心了

标签 ruby methods parameter-passing ruby-hash double-splat

在 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}

但是尝试将哈希作为位置参数传递时,会发生这种情况:

irb(main):002:0> example({something: 42})
[]
{:something=>42}

我希望*args采用{something: 42},而不是**kwargs

位置参数必须是可选的,但即使 *argsarg=nil,double-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"}

当方法也采用 ** 时,如何将哈希作为位置参数传递?

最佳答案

管理起来总是很棘手,因为这里的 **kwargs 会主动获取该散列的所有权。这也会给调用者带来一些困惑,因为无论您做什么,他们在调用它时都必须小心:

# Is this options or the body? It's not clear.
example({ payload: true })

我建议切换到更明确的内容,例如:

def example(**kwargs)
  body = kwargs.delete(:body)
end

然后这样调用它:

example(body: { ... }, user: "username", ...)

如果你能拼出允许的参数,那就更好了:

def example(body: nil, user: nil, password: nil)
  # ...
end

关于Ruby double splat 参数对于 Hash 参数来说太贪心了,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45017992/

相关文章:

ruby - 在 Ruby 中,if/elsif/else 语句的从属 block 是否与作为参数传递的 'block' 相同?

ruby - 在 ruby​​ on rails 中使用哈希

javascript - 如何使用 Array.filter 而不是传统的循环 O(n^2)?

c# - 我如何创建和调用没有任何参数的方法?

javascript - 如何将 JSF 托管 bean 属性传递给 JavaScript 函数?

batch-file - 读取批处理文件中参数的每个字符

mysql - configuration.rb :14:in `instance_eval' : (eval):16: syntax error, 意外的输入结束,期待

ruby-on-rails - rails : Using CanCan to define multiple roles depending on instances of single Model?

java - Java什么时候读取方法字节码?

iphone - PhoneGap.exec() 在 JS 和 Obj-C 之间传递对象