2

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

  # 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

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

IdentANode.rb:14:in collect': undefined methodcollect' for 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?

return 语句没有执行,什么给出?为什么这两种说法有区别?unless关键字有多个条件会导致问题吗?

任何想法,将不胜感激

4

2 回答 2

5

你那里有一个逻辑故障。您正在测试它们是否都是 nil为了避免在您应该测试是否nil. 你可能因为有太多的否定层而让自己陷入这种境地。任何超过一个都是不可接受的。

换句话说,您可以选择“如果没有下雨”,但不应该使用“除非is_not_raining标志未设置为 false 的倒数”之类的内容。

我个人的观点是,除非很明显它们存在,否则不应使用尾随条件。正如您在示例中看到的,您必须水平滚动才能找到条件,向开发人员隐藏重要信息。

就风格而言,不要使用not何时!会做同样的工作。其次,您正在专门针对nil您可能只需要某种定义的值进行测试。

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

您的代码的正确 Ruby 样式版本是:

if (@ident_a_node and @id)
  return { "IdentANode" => [ @id, ",", @ident_a_node.collect ] }
end  
于 2012-06-21T17:48:41.407 回答
2

除非与和/或一起使用,否则不要使用,这简直令人困惑。unless @ident_a_node.nil? and @id.nil?表示if !(@ident_a_node.nil? and @id.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?
于 2012-06-21T17:44:51.930 回答