4

是否有更简洁和惯用的方法来编写以下代码,该代码用于为方法指定可选参数(在 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

4 回答 4

14

一个常见的模式是使用

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

您最终将options成为一个包含传入值的散列,其中默认散列中的选项与未提供的任何选项相同。

于 2009-12-29T00:21:34.903 回答
2

Ruby 2.0.0有一个新的特性关键字 参数

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

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'
于 2013-11-01T11:50:37.197 回答
0

我想你正在寻找这个

params = { :verbose => true }.merge(params)
于 2009-12-29T00:27:30.590 回答
0

另一种更简洁的写法是

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

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

于 2013-11-01T11:23:32.610 回答