为什么ruby中没有NilReferenceError?

时间:2016-01-15 01:03:15

标签: ruby-on-rails ruby null

为什么NoMethodError没有区分Ruby中的nil

在nil上调用方法是一个非常常见的错误,通常是由提供给程序的错误数据引起的。任何其他类的NoMethodError通常意味着代码本身出错(例如,为什么你在reconnect上调用Document?代码中可能存在错误。

如果我将以下代码添加到项目中会产生哪些问题?

NilReferenceError = Class.new(NoMethodError)
class NilClass
  def method_missing(symbol, *args)
    raise NilReferenceError, "undefined method `#{symbol}' for nil:NilClass", caller
  end
end

我想这样做是因为当我对异常进行分类时,NilReferenceError可能是由错误的数据引起的,根本原因很可能是在另一个位置(例如,输入的验证)。相比之下,NoMethodError可能是一个完全根据异常行编写的编程错误(更容易修复,并且很可能100%发生)。

将类似代码添加到我的项目中有什么负面影响?

3 个答案:

答案 0 :(得分:1)

我认为这只是其他编程语言的习惯。在ruby中,nil是一个第一类对象,如整数,散列或您自己的类对象。

一旦看到"NoMethodError: undefined method xxx for nil:NilClass"错误一次或两次,就会习惯它。

答案 1 :(得分:0)

你的意思是,在做b=nil; b.say_hello;这样的事情时,ruby会给你"未定义的方法`say_hello'对于nil:NilClass( NoMethodError )"而不是像(在你的说法中)那样的东西"未定义的方法`say_hello' for nil:NilClass( NilReferenceError )"?

Ruby没有错,因为nil是一个像其他对象一样的对象。它有to_s之类的方法,所以ruby不能通过提出异常来禁止任何调用"因为它是零,你不能做任何事情。我会给你一个NilReferenceError"。

如果你知道你正在做的事情可能会阻止ruby的默认行为,你肯定可以像上面的代码一样。

答案 2 :(得分:0)

monkeypatching nil显示更具描述性的错误消息没有错,但它无法解决问题的根本原因,即编码实践允许和传播nil值。

考虑以下非常人为的例子:

def do_something(input)
  object = fetch_something_with(input[element])
  do_something_with(object)
end

这可能会爆发几种方式:

  • input哈希不包含element,并将nil传递给fetch_something_with
  • fetch_something_with返回nil(按设计或失败时),将其传递到do_something_with

另一种方法可能是:

def do_something(input)
  object = fetch_something_with(validated_input)

  object && return do_something_with(object)
end

def validated_input(input)
  input.fetch(element) # fetch raises an exception if the value is not present
end

稍微多一些代码,但它让我们高枕无忧,这段代码不会默默地将nil传递给线路,以便稍后失败。

当然,在每种方法中成为这种偏执都没有意义,但是在方法或对象层面上,在代码中有一个深思熟虑的边界是一种好习惯。 nil经常出现问题表明这些边界需要加强。