我有以下代码:
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之前。我不明白为什么?我怎么能像我期望的那样改变文件方法呢?
答案 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上调用。在您的第一个用法示例中,您在一个语句中引发了这两个错误。在第二个用法示例中,错误是顺序的。不过,他们应该产生相同的结果,他们也会为我做。