Ruby - 关键字参数 - 你能把所有的关键字参数当作一个哈希值吗?如何? [英] Ruby - Keyword Arguments - Can you treat all of the keyword arguments as a hash? How?

查看:19
本文介绍了Ruby - 关键字参数 - 你能把所有的关键字参数当作一个哈希值吗?如何?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个看起来像这样的方法:

I have a method that looks like this:

def method(:name => nil, :color => nil, shoe_size => nil) 
  SomeOtherObject.some_other_method(THE HASH THAT THOSE KEYWORD ARGUMENTS WOULD MAKE)
end

对于任何给定的调用,我可以接受可选值的任意组合.我喜欢命名参数,因为我只需查看方法的签名即可查看可用的选项.

For any given call, I can accept any combination of optional values. I like the named arguments, because I can just look at the method's signature to see what options are available.

我不知道是否有我在上面的代码示例中用大写字母描述的快捷方式.

What I don't know is if there is a shortcut for what I have described in capital letters in the code sample above.

在过去,它曾经是:

def method(opts)
  SomeOtherObject.some_other_method(opts)
end

优雅,简单,近乎作弊.

Elegant, simple, almost cheating.

这些关键字参数是否有快捷方式,还是我必须在方法调用中重构我的选项哈希?

Is there a shortcut for those Keyword Arguments or do I have to reconstitute my options hash in the method call?

推荐答案

是的,这可能的,但不是很优雅.

Yes, this is possible, but it's not very elegant.

您必须使用 parameters method,它返回方法参数及其类型的数组(在这种情况下,我们只有关键字参数).

You'll have to use the parameters method, which returns an array of the method's parameters and their types (in this case we only have keyword arguments).

def foo(one: 1, two: 2, three: 3)
  method(__method__).parameters
end  
#=> [[:key, :one], [:key, :two], [:key, :three]]

知道这一点后,有多种方法可以使用该数组来获取所有参数及其提供的值的哈希值.

Knowing that, there's various ways how to use that array to get a hash of all the parameters and their provided values.

def foo(one: 1, two: 2, three: 3)
  params = method(__method__).parameters.map(&:last)
  opts = params.map { |p| [p, eval(p.to_s)] }.to_h
end
#=> {:one=>1, :two=>2, :three=>3}

所以你的例子看起来像

def method(name: nil, color: nil, shoe_size: nil)
  opts = method(__method__).parameters.map(&:last).map { |p| [p, eval(p.to_s)] }.to_h
  SomeOtherObject.some_other_method(opts)
end

仔细考虑使用它.它很聪明,但以可读性为代价,其他阅读您的代码的人不会喜欢它.

Think carefully about using this. It's clever but at the cost of readability, others reading your code won't like it.

您可以使用辅助方法使其更具可读性.

You can make it slightly more readable with a helper method.

def params # Returns the parameters of the caller method.
  caller_method = caller_locations(length=1).first.label  
  method(caller_method).parameters 
end

def method(name: nil, color: nil, shoe_size: nil)
  opts = params.map { |p| [p, eval(p.to_s)] }.to_h
  SomeOtherObject.some_other_method(opts)
end

更新: Ruby 2.2 引入了 Binding#local_variables 可以用来代替 Method#parameters.请小心,因为在方法内定义任何其他局部变量之前,您必须调用 local_variables.

Update: Ruby 2.2 introduced Binding#local_variables which can be used instead of Method#parameters. Be careful because you have to call local_variables before defining any additional local variables inside the method.

# Using Method#parameters
def foo(one: 1, two: 2, three: 3)
  params = method(__method__).parameters.map(&:last)
  opts = params.map { |p| [p, eval(p.to_s)] }.to_h
end
#=> {:one=>1, :two=>2, :three=>3}

# Using Binding#local_variables (Ruby 2.2+)
def bar(one: 1, two: 2, three: 3)
  binding.local_variables.params.map { |p|
    [p, binding.local_variable_get(p)]
  }.to_h
end
#=> {:one=>1, :two=>2, :three=>3}

这篇关于Ruby - 关键字参数 - 你能把所有的关键字参数当作一个哈希值吗?如何?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆