Ruby:使用带有return语句的unless关键字

时间:2012-06-21 17:38:06

标签: ruby

我目前正在开发一个项目,我的代码如下所示:

  # the first return is the one causing problems
  def collect
    return Hash["IdentANode", Array[@id, ",", @ident_a_node.collect]] unless @ident_a_node.nil? and @id.nil?
    return Hash["IdentANode", @id] unless @id.nil?
  end

我使用unless运算符有条件地执行return语句。出于某种原因,即使@ident_a_nodenil,此代码仍会执行。执行时我收到此消息:

  

IdentANode.rb:14:在collect': undefined method收集'中   nil:NilClass(NoMethodError)

这使我感到困惑,因为我曾认为,除非关键字会阻止这种情况发生。当我将语句更改为此表单时:

if not @ident_a_node.nil? and not @id.nil?
  return Hash["IdentANode", Array[@id, ",", @ident_a_node.collect]]
end  

或此表格:

return Hash["IdentANode", Array[@id, ",", @ident_a_node.collect]] if not @ident_a_node.nil? and not @id.nil?

返回语句是不是执行的,是什么给出的?为什么这两个陈述有区别?使用unless关键字的多个条件会导致问题吗?

任何想法都将不胜感激

2 个答案:

答案 0 :(得分:4)

你的逻辑失败了。您正在测试他们 nil以避免在您应该测试时运行它 nil。你可能通过过多的否定层面来解决这个问题。任何不止一个都是不可接受的。

换句话说,你可以逃脱“如果它没有下雨”但不应该使用“除非is_not_raining标志没有设置为假的倒数”之类的东西。

我个人认为,除非显而易见,否则不应使用拖尾条件。正如您在示例中所看到的,您必须水平滚动才能找到条件,隐藏开发人员的重要信息。

作为一种风格问题,当not执行相同的工作时,请勿使用!。其次,当你可能只想要某种定义的值时,你会专门针对nil进行测试。

其他问题包括使用Hash[]Array[]这些肯定是使用需要它们的语言的工件。与JavaScript一样,Ruby允许分别使用{ }[ ]隐式声明这些内容。

适当的Ruby风格版本的代码是:

if (@ident_a_node and @id)
  return { "IdentANode" => [ @id, ",", @ident_a_node.collect ] }
end  

答案 1 :(得分:1)

不要使用,除非和/或,它只是简单的混淆。 unless @ident_a_node.nil? and @id.nil?表示if !(@ident_a_node.nil? and @id.nil?),这意味着只要两个实例变量中的一个不是nil,它就会返回。

if !(@ident_a_node.nil? and @id.nil?)

相同
if !@ident_a_node.nil? or !@id.nil?

哪个应该更清楚,为什么它与

不一样
if not @ident_a_node.nil? and not @id.nil?