条件链成功应该是隐含的还是明确的

时间:2013-05-01 00:13:46

标签: ruby coding-style

哪种更好的做法?在条件链中隐含或显式成功案例的逻辑?

请注意,以下所有内容的逻辑都是详尽无遗的,所以这实际上是一个风格问题。

def foobar(foo, bar)
  if not foo
    "No foo"
  elsif not bar
    "No bar"
  else
    "foobar"
  end
end

替代隐含

def foobar(foo, bar)
  return "No foo" if not foo
  return "No bar" if not bar

  "foobar"
end

def foobar(foo, bar)
  if not foo
    "No foo"
  elsif not bar
    "No bar"
  elsif foo && bar
    "foobar"
  end
end

替代显式表格

def foobar(foo, bar)
  if foo
    if bar
      "foobar"
    else
      "No bar"
    end
  else
    "No foo"
  end
end

1 个答案:

答案 0 :(得分:4)

虽然这通常归结为个人偏好的问题,其中所有给定的解决方案具有相同的功能属性,但我发现在大多数情况下最容易阅读的解决方案将是最好的。容易因人而异,因为任何来自C ++,Java或Perl背景的人都可能对复杂性有更高的容忍度。

有些纯粹主义者会让你相信每个方法应该有一个入口点和一个出口点,即最后有一个单数return,但这看起来像没有真正基础的教条。

“短路”方法,您将使用return ifreturn unless测试提前终止方法,可以预先建立“禁止”条件并避免不必要地缩进稍后会有更复杂的代码。这类似于:

def complicated_method
  return if (@safety == :on)
  return unless (Time.now >= @launch_time)

  # ...
end

这与您的“替代隐式”示例相对应。

你应该尽量避免双重否定条件,即使是在不经意间。如果你对此粗心大意,你可以很容易地得到双重,三重甚至是令人费解的四重否定条件。例如:

if (not @do_not_launch != true)
  # Triple negation: If not not launch is not true
else
  # Quadruple negation: If not not not launch is not true
end

很快,您应该将核导弹发射程序放在哪一个内,哪一个发出警告?

通常,除了if not之外,使用unless,除非您有else条款。

从Ruby风格的角度看,not以长格式使用也是不寻常的。通常情况下,它可以通过使用unless来避免,也可以显示为!版本,它更严格地绑定,并且不太可能显着改变逻辑的含义。与andor一样,松散绑定的逻辑运算符可能很滑,无法一致地应用,因为在某些情况下,它们的使用会导致过多的歧义并出现语法错误。

例如,以下内容无效:

x = not y and z

紧密绑定的替代方案可以按照您的预期运作:

x = !y && z

因此,我能想到的最佳版本是:

def foobar(foo, bar)
  return "No foo" unless (foo)
  return "No bar" unless (bar)

  "foobar"
end