假设我想要一个像这样调用的方法:
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方法是什么?
答案 0 :(得分:21)
def foo(options = {})
options = { ... defaults ... }.merge(options)
end
答案 1 :(得分:18)
如果您使用的是Rails(不仅仅是普通的Ruby),则会使用稍微短一些的方法
def foo(options = {})
options.reverse_merge! { ... defaults ... }
end
这样做的另一个好处是可以让你更干净地做多行:
def foo(options = {})
options.reverse_merge!(
:some_default => true,
:other_default => 5
)
end
答案 2 :(得分:6)
通常最好将安全默认值封装在声明为常量的哈希值中。例如:
要求'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
重要的是要注意,在合并Hash对象时,String和Symbol键是不同的,并且不会像您期望的那样组合。在Rails环境中,您始终可以使用Hash#symbolize_keys将其转换为另一个,或者将它们声明为HashWithIndifferentAccess,它会为您绘制差异。
答案 3 :(得分:4)
如果有人从谷歌看到这个,这个问题已经过时了。现代和更清晰的答案(使用Ruby&gt; 2.0)是使用关键字参数。它们有几个优点。
1。)您可以在散列中要求密钥的名称。 (在ruby&gt; 2.1中)
2。)你不必在函数中“解包”散列。这些键只是作为变量交给你的。 (因此你不必像speed = opts[:speed]
)
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
答案 4 :(得分:0)
Rails 6(不知道从哪个版本提供)具有语义别名:
def a_method(options={})
options.with_defaults!(
a_key: :a_default_value,
b_key: :b_default_value,
..
)
..
end