Есть ли идиоматический способ указать значения по умолчанию для необязательных параметров в Ruby?
Есть ли более краткий и идиоматический способ написания следующего кода, который используется для указания значений по умолчанию для необязательных параметров (в хэше 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]
, чтобы покрыть случаи, когда вы хотите указать значение "ложь" (т.е., если вы хотите передать :verbose => false
в качестве аргумента в этом примере).
Я понимаю, что в этом простом примере я мог бы легко сделать:
def initialize(verbose=false)
@verbose = verbose
end
но в моем реальном коде у меня фактически есть куча необязательных параметров (в дополнение к нескольким обязательным), и я хотел бы поместить необязательные параметры в хэш params, чтобы я мог легко указать (по имени) только несколько что я хочу, вместо того, чтобы перечислить их все по порядку (и, возможно, придется перечислить те, которые я на самом деле не хочу).
4 ответа
Распространенным примером является использование
def foo(options = {})
options = { :default => :value }.merge(options)
end
Вы закончите с options
будучи хэшем, содержащим переданные значения, с параметрами из вашего хэша по умолчанию, такими как те, которые не были предоставлены.
В 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'
Другой способ написать это, более кратко, было бы
def foo(options = {})
options.reverse_merge! value1: true, value2: 100
end
Это устанавливает для параметров [: значение1] значение true (значение по умолчанию), если переданные параметры уже не содержат ключ: значение1. То же самое для:value2
Я думаю, что вы ищете это
params = { :verbose => true }.merge(params)