2013-03-03 71 views
1

您可以使用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) 

如果不是原生ruby,Rails添加了類似這樣的東西嗎?

目前我大致是這樣做有

foo('arg1', opts.merge(hash1: 'foo')) 
+0

如果你在談論默認選項,那麼是'merg e'是要走的路。 – texasbruce 2013-03-03 22:07:33

+0

是否有任何理由,你顛倒了順序,而不是做'{hash1:'foo'}。merge(opts)'? – sawa 2013-03-03 22:24:57

+0

@sawa不是。只是自然出現了。 – Drew 2013-03-04 01:51:00

回答

2

有沒有這樣的事情(儘管它已經提出)。由於這會改變解析規則,因此無法在Ruby中實現。我能想到的最好的是哈希定義*

class Hash; alias :* :merge end 

,並通過以下方式之一使用它:

foo('arg1', {hash1: 'foo'}*opts) 
foo('arg1', {hash1: 'foo'} *opts) 
foo('arg1', {hash1: 'foo'}. *opts) 

其中最後一個我認爲是合理地接近你想要的。

+0

也許使用'+'而不是'*'會更有意義? – 2013-03-03 22:39:43

+0

@AndrewMarshall我同意這一點。我想讓它看起來接近摔跤運營商。 – sawa 2013-03-03 22:40:56

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 
+0

恩,這是否回答你的問題?不要忘記[upvote /接受你的問題的答案](http://meta.stackexchange.com/a/5235/158402)':)' – 2013-06-02 12:35:03

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)