Ruby风格:从哈希中获取默认值

4

假设我有一个opts哈希表,其中可能缺少一些键,那么什么是更好或更符合惯例的Ruby代码?这个:

my_val = opts.delete(:key){|k| default_value_for_key }

或者:

my_val = opts.delete(:key) || default_value_for_key

考虑到我想在提取值时从哈希表中删除键。


第二个样本非常易读。 - the Tin Man
这一直是我做这种事情的默认方法,但最近我发现有些代码是用第一种方式实现的,所以让我感到好奇。 - rainkinz
请注意,这两段代码并不总是做相同的事情。考虑该值为 nil 的情况。 - Andrew Marshall
好的,它能工作,但是#2的效果更好,视觉噪点更少。 - the Tin Man
1
@AndrewMarshall 提出了一个很好的观点。了解你将要得到的有效载荷的类型非常重要。如果你不知道,那么你必须对你的编码更加谨慎,这种情况下 #1 更安全。 - the Tin Man
2个回答

3
我认为你可以使用默认选项fetch
my_val = opts.fetch(:key, "default_value_for_key")

编辑:

考虑到您想要删除键,块形式是我个人认为更好的选择,因为它将返回块评估的任何内容。

但是,第二个选项更容易理解。


是的,我喜欢那个。不过把哈希表中的键删除这一点我没有说清楚。我已经更新了我的问题。 - rainkinz

2

关键字参数:

如果您正在使用 Ruby 2.0 或更高版本,最常见的做法是使用关键字参数

def foo(bar: 10)
  # do something with bar
end

关键字参数功能会自动处理默认值,并在提供未知键时抛出异常。
如果您没有使用Ruby 2.0,或者由于某些其他原因关键字参数不起作用,您应该决定您的方法是否会检测未知键并抛出错误,还是只是静默地忽略它们。
静默地忽略未知键:
def foo(opts={})
  bar = opts.fetch(:bar, 10)
  # do something with bar
end

使用fetch比使用opts[:bar] || 10更好,因为它允许方法的调用者指定bar=nilbar=false。如果使用||运算符,会覆盖来自哈希的任何值,如果它为nil或false。
关于未知键的投诉:
如果你有很多键,并且希望在给出未知键时抛出异常,则可能应该使用delete。思路是,当你删除已知键后,只有未知键留下。
def foo(opts={})
  opts = opts.dup   # Avoid deleting from the hash the caller passed
                    # in because that would surprise the caller!

  bar = opts.delete(:bar) { 10 }
  # get other options

  raise "Unknown keys #{opts.keys.inspect}" if !opts.empty?

  # do stuff
end

上一个例子正是我所考虑要做的。谢谢。 - rainkinz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接