2012-08-13 73 views
5

這是設置在Ruby中默認的常用方法:製作一個選項虛假默認

class QuietByDefault 
    def initialize(opts = {}) 
    @verbose = opts[:verbose] 
    end 
end 

這是一個容易陷阱落入:

class VerboseNoMatterWhat 
    def initialize(opts = {}) 
    @verbose = opts[:verbose] || true 
    end 
end 

這是一個正確的辦法做到這一點:

class VerboseByDefault 
    def initialize(opts = {}) 
    @verbose = opts.include?(:verbose) ? opts[:verbose] : true 
    end 
end 

什麼是編寫最好的/乾淨的方式? (我能因素出來,當然)。

什麼模式被廣泛使用,如果有的話,在Ruby代碼有什麼看法? ActiveSupport有這樣的模式嗎? (最小的更好 - 我並不需要一個完整的命令行選項解析器)

咆哮P.S:我不喜歡這樣處理,處理默認false選項默認true與代碼的代碼之間的不對稱。而不會導致錯誤 - - 這使得兩者之間改變的模式將看到一件好事。

回答

7

一個簡單的方法來做到這是通過使用第二個參數散列#取

class VerboseByDefault 
    def initialize(opts = {}) 
    @verbose = opts.fetch(:verbose, true) 
    end 
end 

對於複雜的默認值,取也可以採取一個塊,其中執行如果該值不是在哈希。請參閱:http://ruby-doc.org/core-1.9.3/Hash.html#method-i-fetch

+0

很不錯的!我*以前可能見過這個,但我不記得它。謝謝! – 2012-08-14 02:04:07

1

我經常看到它設置所有的默認設置,然後與OPTS將它們合併。如..

def initialize(opts = {}) 
    @options = { :verbose => false, :foo => 42 } 
    @options.merge!(opts) 
    # ... 
end 

這樣所有選項在一個地方設置,你只合並用戶提供的。

+0

我喜歡默認啓動和用戶提供的選項合併的想法,但你已經在你的範圍如何'有一個錯誤@ options'!看你的'自我'。 :) – 2012-08-13 18:04:46

+0

哦對不起,這是不是意味着作爲一個完整的解決方案:)我將修改它,並把它放在裏面...... – Doon 2012-08-13 18:29:03

0
require 'active_support/core_ext/hash/reverse_merge' 
class VerboseByDefault 
    DEFAULTS = { verbose: true } 
    def initialize(opts = {}) 
    opts.reverse_merge!(DEFAULTS) 
    @verbose = opts[:verbose] 
    end 
end 

這不僅僅是一個選項的小清潔劑,但如果您有更多的選擇,它會變得更好。同時,它採用了truefalse相同的模式。