默认情况下将选项设为false

时间:2012-08-13 17:39:17

标签: ruby options

这是在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

编码VerboseByDefault的最佳/最干净方法是什么? (当然,我可以将其考虑在内。)

一般来说,在Ruby代码中广泛使用哪种模式(如果有的话)? ActiveSupport是否有这种模式? (最小值更好 - 我不需要完整的命令行选项解析器。)

Ranting P.S。:我不喜欢处理默认true的代码与处理默认false选项的代码之间的不对称。在两者之间进行更改的模式 - 不会导致错误 - 将是一件好事。

3 个答案:

答案 0 :(得分:7)

一种简单的方法是使用Hash #fetch

的第二个参数
class VerboseByDefault
  def initialize(opts = {})
    @verbose = opts.fetch(:verbose, true)
  end
end

对于复杂的默认值,fetch也可以使用一个块,如果该值不在哈希值中,则执行该块。请参阅:http://ruby-doc.org/core-1.9.3/Hash.html#method-i-fetch

答案 1 :(得分:1)

我经常将其视为设置所有默认值,然后将它们与opts合并。比如..

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

这样,您可以在一个地方设置所有选项,只需合并用户提供的选项。

答案 2 :(得分: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使用相同的模式。