2009-06-10 35 views

回答

16

如果您使用Rails的(不只是簡單的紅寶石),稍短的方法是

def foo(options = {}) 
    options.reverse_merge! { ... defaults ... } 
end 

這有讓您一點點位更乾淨做多行的附加好處:

def foo(options = {}) 
    options.reverse_merge!(
    :some_default => true, 
    :other_default => 5 
) 
end 
+1

正是我在找的,謝謝。我還發現,如果您不使用Rails,那麼Facets gem也會使用reverse_merge猴子修補Hash!方法。 – 2009-06-11 20:36:35

19
def foo(options = {}) 
    options = { ... defaults ... }.merge(options) 
end 
4

通常最好將安全的默認值封裝在一個哈希聲明爲常量。例如:

需要「ostruct」

require 'ostruct' 

class Tiger < OpenStruct 
    DEFAULTS = { 
    :num_stripes => 12, 
    :max_speed => 43.2 
    }.freeze 

    def initialize(options = { }) 
    super(DEFAULTS.merge(options)) 
    end 
end 

tiger = Tiger.new(:max_speed => 19.95) 

puts tiger.max_speed 
puts tiger.num_stripes 

合併哈希對象的字符串和符號鍵是不同的,不會合並如你所料時的注意事項是很重要的。在Rails環境中,您可以始終使用Hash#symbolize_keys將它們轉換爲另一個,或者將它們聲明爲HashWithIndifferentAccess,從而爲您消除差異。

3

如果有人從谷歌這看到這個問題,這個問題是舊的和過時的。現代和更乾淨的答案(與Ruby> 2.0)是使用關鍵字參數。他們有幾個優點。

1.)你可以在散列中要求密鑰的名稱。 (在紅寶石> 2.1)

2.)你不必「解開」函數中的散列。鑰匙只是作爲變量交給你。 (因此你不必做這樣speed = opts[:speed]

3)它是清潔

def foo(num_stripes: 12, **rest) 
    print num_stripes, rest 
end 

foo({max_speed: 42}) # would print '12, {max_speed: 42}' 

看到完整的紅寶石文檔瀏覽:http://www.ruby-doc.org/core-2.1.0/doc/syntax/methods_rdoc.html#label-Array%2FHash+Argument

這裏好一點兒的博客文章:http://robots.thoughtbot.com/ruby-2-keyword-arguments