Какой хороший чистый способ использовать хэш параметров со значениями по умолчанию в качестве параметра в ruby
предположим, мне нужен метод, который будет называться так:
tiger = create_tiger( :num_stripes => 12, :max_speed => 43.2 )
tiger.num_stripes # will be 12
где некоторые параметры имеют значения по умолчанию:
tiger = create_tiger( :max_speed => 43.2 )
tiger.num_stripes # will have some default value
каков хороший идиоматический ruby-способ реализации этого поведения по умолчанию в реализации метода?
4 ответов
Если вы используете Rails (а не просто Ruby), немного более короткий метод -
def foo(options = {})
options.reverse_merge! { ... defaults ... }
end
это имеет дополнительное преимущество, позволяя вам делать несколько линий, немного более чистоплотными:
def foo(options = {})
options.reverse_merge!(
:some_default => true,
:other_default => 5
)
end
обычно лучше инкапсулировать безопасные значения по умолчанию в хэш, объявленный как константа. Например:
требуется 'ostruct'
require 'ostruct'
class Tiger < OpenStruct
DEFAULTS = {
:num_stripes => 12,
:max_speed => 43.2
}.freeze
def initialize(options = { })
super(DEFAULTS.merge(options))
end
end
tiger = Tiger.new(:max_speed => 19.95)
puts tiger.max_speed
puts tiger.num_stripes
при слиянии хэш-объектов важно отметить, что ключи String и Symbol различны и не будут объединены, как можно было бы ожидать. В среде Rails вы всегда можете конвертировать один в другой, используя хэш#symbolize_keys или объявив их как HashWithIndifferentAccess, который отображает разницу для вы.
в случае, если кто-то видит это из google, этот вопрос устарел и устарел. Современный и гораздо более чистый ответ (с Ruby > 2.0) - использовать аргументы ключевых слов. У них есть несколько преимуществ.
1.) вы можете потребовать имя ключа в хэше. (в ruby > 2.1)
2.) вам не нужно "распаковывать" хэш в функции. Ключи просто вручены вам как переменные. (таким образом, вам не нужно делать like speed = opts[:speed]
)
3.) Это чище!--3-->
def foo(num_stripes: 12, **rest)
print num_stripes, rest
end
foo({max_speed: 42}) # would print '12, {max_speed: 42}'
см. полные документы ruby здесь: http://www.ruby-doc.org/core-2.1.0/doc/syntax/methods_rdoc.html#label-Array%2FHash+Argument
и хороший маленький пост в блоге здесь:http://robots.thoughtbot.com/ruby-2-keyword-arguments