Ruby 默认情况下使选项为false

Ruby 默认情况下使选项为false,ruby,options,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 Verbose

这是在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对此有模式吗?(Minimal更好——我不需要完整的命令行选项解析器。)


咆哮附言:我不喜欢处理默认
true
的代码与处理默认
false
选项的代码之间的不对称。一种模式可以在这两者之间进行更改,而不会引起bug,这将是一件好事。

我通常将其视为设置所有默认值,然后将它们与opt合并。例如

def initialize(opts = {})
  @options = { :verbose => false, :foo => 42 } 
  @options.merge!(opts)
  # ...
end
这样,所有选项都设置在一个位置,您只需合并用户提供的选项

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

这不仅对一个选项来说更干净,而且如果你有更多的选项,它会变得更好。另外,它对
true
false
使用相同的模式。一种简单的方法是使用第二个参数散列#fetch


对于复杂的默认值,fetch还可以获取一个块,如果该值不在散列中,则执行该块。请参阅:

我喜欢从默认值开始并在用户提供的选项中合并的想法,但是您在如何定义
@options
的范围方面有一个bug!注意你的
自我
:)哦,对不起,这不是一个完整的解决方案:)我会编辑它,并把它放在里面…非常好!我以前可能见过,但我不记得了。谢谢
class VerboseByDefault
  def initialize(opts = {})
    @verbose = opts.fetch(:verbose, true)
  end
end