为什么ruby没有提出例外?

时间:2012-09-17 21:38:56

标签: ruby exception-handling

我有以下代码:

require 'open-uri'

class CustomException < StandardError;end

def file
  f = Kernel.open('http://i.dbastatic.dk/images/2/68/500656768_20012012182407_0401_2.jpg')
  return f
rescue => e
  raise CustomException.new(e.message)
end

现在,如果我执行以下操作:

begin
  file.body
rescue CustomException
  puts "rescued it!"
end

我明白了:

  

NoMethodError:nil的未定义方法`body':NilClass

而不是带有来自打开uri的404错误消息的CustomException。奇怪的是,如果我改为:

begin
  f = file
  f.body
rescue CustomException
  puts "rescued it!"
end

然后它工作,我得到了我可以捕获的CustomException,在它尝试做.body之前。我不明白为什么?我怎么能像我期望的那样改变文件方法呢?

3 个答案:

答案 0 :(得分:2)

只需稍加修改即可显示问题:

require 'open-uri'

def file
  f = Kernel.open('fill_in_some_url_that_returns_a_404')
  return f
rescue => e
  puts e.message
  1 ##<<---- inserted
end

file.body

不,你得到undefined method 'body' for 1:Fixnum

说明: 您的方法执行puts e.message,但它不返回结果(换句话说:它返回nil。)

使用file.body,您可以调用file(结果为nil)。在这个结果上你打电话给body。但nil不存在这种情况。因此,您收到错误undefined method 'body' for nil:NilClass

如果我尝试

f = file
f.body

我得到了同样的错误。

您确定,在两个电话中使用相同的网址吗?如果您可以打开您的网址,则会重新启动有效对象。


实际上,如果没有更多代码,我就无法看到你的问题。

您可以检查一下代码:

如果您定义变量方法file,那么您将获得变量。见下面的例子。也许这就是问题所在。

file = nil
def file
  1
end

file.body   #undefined method `body' for nil:NilClass (NoMethodError)
file().body #undefined method `body' for 1:Fixnum (NoMethodError)

为了确保获得该方法,您可以尝试file()

答案 1 :(得分:1)

我觉得你很困惑。您展示的唯一代码似乎就是这个问题:

require 'open-uri'

class CustomException < StandardError;end

def file
  f = Kernel.open('http://www.google.com/blahblah')
  return f
rescue => e
  raise CustomException.new(e.message)
end

begin
  file.body
rescue CustomException
  puts "rescued it!"
end

好吧,我运行了那段代码,我得到了“救了它!”这不是人们所期望的吗?我永远不会得到NoMethodError: undefined method body for nil:NilClass,而且我也不相信你所做的代码。

那是什么问题,真的吗?难道404消息没有传递给stdout吗?如果这就是你想要的,你应该写下:

require 'open-uri'

class CustomException < StandardError;end

def file
  f = Kernel.open('http://www.google.com/blahblah')
  return f
rescue => e
  raise CustomException.new(e.message)
end

begin
  file.body
rescue CustomException => e
  puts "rescued it!", e.message
end

答案 2 :(得分:0)

这可能是你想要的:

require 'open-uri'

def file(url)
 begin
  Kernel.open(url)
 rescue => e
  puts e.message
 end
end

让我们先尝试一个有效的网址:

f = file('http://www.google.com/')
puts f.read if !f.nil?

现在让我们尝试使用返回404的网址:

f = file('http://www.google.com/blahblah')
puts f.read if !f.nil?

编辑:在不存在的URL上调用时,您的代码会引发两个错误。 'file'方法引发OpenURI :: HTTPError,而'body'方法引发NoMethodError,因为它在nil上调用。在您的第一个用法示例中,您在一个语句中引发了这两个错误。在第二个用法示例中,错误是顺序的。不过,他们应该产生相同的结果,他们也会为我做。