是否有一种惯用的方法来为Ruby中的可选参数指定默认值?

时间:2009-12-29 00:18:03

标签: ruby idioms

是否有更简洁和惯用的方法来编写以下代码,用于为方法指定可选参数(在params / options哈希中)的默认值?

def initialize(params={})
  if params.has_key? :verbose
    @verbose = params[:verbose]
  else
    @verbose = true # this is the  default value
  end
end

我希望将它简化为类似的东西:

def initialize(params={})
  @verbose = params[:verbose] or true
end

哪个几乎有效,除了您确实需要使用has_key? :verbose作为条件,而不是仅仅评估params[:verbose],以便涵盖您想要指定的情况值为'false'(即如果您想在此示例中传递:verbose => false作为参数)。

我意识到在这个简单的例子中我可以很容易地做到:

def initialize(verbose=false)
  @verbose = verbose
end

但是,在我的实际代码中,我实际上有一堆可选参数(除了一些必需的参数),我想把可选的参数放在params哈希中,这样我就可以轻松地指定(按名称) )我想要的少数,而不是必须按顺序列出它们(并且可能必须列出我实际上不想要的那些)。

4 个答案:

答案 0 :(得分:14)

常见的模式是使用

def foo(options = {})
  options = { :default => :value }.merge(options)
end

您最终将options作为包含传入值的哈希值,并使用默认哈希值中的选项作为未提供的选项。

答案 1 :(得分:2)

Ruby 2.0.0 有一项新功能keyword arguments

以前你必须编写这样的代码:

def foo(options = {})
  options = {bar: 'bar'}.merge(options)
  puts "#{options[:bar]} #{options[:buz]}"
end

foo(buz: 'buz') # => 'bar buz'

现在这更清洁了:

def foo(bar: 'bar', **options)
  puts "#{bar}, #{options}"
end

foo(buz: 'buz') # => 'bar buz'

答案 2 :(得分:0)

我认为你正在寻找这个

params = { :verbose => true }.merge(params)

答案 3 :(得分:0)

另一种写作方式,更简洁,就是

def foo(options = {})
    options.reverse_merge! value1: true, value2: 100
end

除非已经传入选项,否则将选项[:value1]设置为true(默认值) 包含键:value1。相同:value2