您可以使用splat运算符对数组进行解构。
def foo arg1, arg2, arg3
#...Do Stuff...
end
array = ['arg2', 'arg3']
foo('arg1', *array)
但是有没有办法破坏选项类型优点的哈希?
def foo arg1, opts
#...Do Stuff with an opts hash...
end
opts = {hash2: 'bar', hash3: 'baz'}
foo('arg1', hash1: 'foo', *opts)
如果不是原生红宝石,Rails是否添加了这样的东西?
目前我正在用
大致做到这一点foo('arg1', opts.merge(hash1: 'foo'))
答案 0 :(得分:4)
是的,有一种解构散列的方法:
def f *args; args; end
opts = {hash2: 'bar', hash3: 'baz'}
f *opts #=> [[:hash2, "bar"], [:hash3, "baz"]]
问题是你想要的实际上是而不是解构。你想从
开始'arg1', { hash2: 'bar', hash3: 'baz' }, { hash1: 'foo' }
(请记住,'arg1', foo: 'bar'
只是'arg1', { foo: 'bar' }
)
'arg1', { hash1: 'foo', hash2: 'bar', hash3: 'baz' }
根据定义,合并(注意周围的结构 - 哈希 - 如何仍然存在)。而解构则来自
'arg1', [1, 2, 3]
到
'arg1', 1, 2, 3
答案 1 :(得分:3)
现在是2018年,值得更新。 Ruby 2.0 introduced keyword arguments,还有哈希散列运算符**
。现在,您只需执行以下操作即可:
def foo arg1, opts
[arg1, opts]
end
opts = {hash2: 'bar', hash3: 'baz'}
foo('arg1', hash1: 'foo', **opts)
#=> ["arg1", {:hash1=>"foo", :hash2=>"bar", :hash3=>"baz"}]
答案 2 :(得分:2)
没有这样的事情(尽管已经提出过)。由于这将改变解析规则,因此无法在Ruby中实现。我能想到的最好的方法是在哈希上定义*
,如
class Hash; alias :* :merge end
并以下列方式之一使用它:
foo('arg1', {hash1: 'foo'}*opts)
foo('arg1', {hash1: 'foo'} *opts)
foo('arg1', {hash1: 'foo'}. *opts)
我认为最后一个与你想要的完全接近。
答案 3 :(得分:0)
如果您对使用active_support感到满意:
require 'active_support/core_ext/hash/slice.rb'
def foo(*args)
puts "ARGS: #{args}"
end
opts = {hash2: 'bar', hash3: 'baz'}
foo *opts.slice(:hash2, :hash3).values
...或者你可以修补自己的解决方案:
class Hash
def pluck(*keys)
keys.map {|k| self[k] }
end
end
def foo(*args)
puts "ARGS: #{args}"
end
opts = {hash2: 'bar', hash3: 'baz'}
foo *opts.pluck(:hash2, :hash3)