2012-08-13 51 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相同的模式。