为什么ruby没有提出例外?

时间:2021-08-04 23:27:10

I have the following code:

我有以下代码:

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

Now if I do the following:

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

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

I get:

NoMethodError: undefined method `body' for nil:NilClass

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

Instead of the the CustomException with the 404 error message from open uri. The strange thing is, that if I instead do:

而不是使用打开uri的404错误消息的CustomException。奇怪的是,如果我改为:

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

Then it works, I get the CustomException, that I can catch, before it's trying to do the .body. I don't get why? And how can I change the file-method to do as I expect?

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

3 个解决方案

#1


1  

I think you've confused yourself. The only code you've shown that seems to illustrate the problem is this:

我觉得你很困惑。您展示的唯一代码似乎说明了问题:

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

Well, I ran that code, and I got "rescued it!" Isn't that what one would expect? I never get NoMethodError: undefined method body for nil:NilClass and I don't believe that you do, either, with the code you show.

好吧,我运行了那段代码,我得到了“救了它!”这不是人们所期望的吗?我从来没有得到NoM​​ethodError:nil的未定义方法体:NilClass,我也不相信你用你展示的代码。

So what's the problem, really? Is it that the 404 message isn't getting passed out to stdout? If that's what you wanted, you should have written:

那真的是什么问题?难道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


2  

Just a little modification to show the problem:

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

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

No you get a undefined method 'body' for 1:Fixnum

不,你得到一个未定义的方法'body'为1:Fixnum

Explanation: Your method does the puts e.message, but it does not return a result (or in other words: it returns nil.)

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

With file.body you call file (with the result nil). and on this result you call body. But this does not exist for nil. So you get the error undefined method 'body' for nil:NilClass

使用file.body,您可以调用file(结果为nil)。在这个结果你称之为身体。但这不存在为零。所以你得到nil的错误未定义方法'body':NilClass

If I try

如果我试试

f = file
f.body

I get the same error.

我犯了同样的错误。

Are you sure, you use the same url in both calls? If you can open your url, the you retrun a valid object.

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


Actually I can't see your problem without more code.

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

You could check your code for one thing:

你可以检查一下你的代码:

If you define a variable and a method file, then you get the variable. See example below. Perhaps this is the problem.

如果定义变量和方法文件,则获取变量。见下面的例子。也许这就是问题所在。

file = nil
def file
  1
end

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

To be sure to get the method you can try file().

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

#3


0  

This is probably what you want:

这可能是你想要的:

require 'open-uri'

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

Let's try a valid url first:

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

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

And now let's try it with a url that returns a 404:

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

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

Edit: Your code raises two errors when called on non-existing URLs. The 'file' method raises a OpenURI::HTTPError, while the 'body' method will raise a NoMethodError because it's called on nil. In your first usage example, you raise those two errors in one statement. In the second usage example, the errors are sequential. Still, they should yield the same result and they do for me.

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

#1


1  

I think you've confused yourself. The only code you've shown that seems to illustrate the problem is this:

我觉得你很困惑。您展示的唯一代码似乎说明了问题:

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

Well, I ran that code, and I got "rescued it!" Isn't that what one would expect? I never get NoMethodError: undefined method body for nil:NilClass and I don't believe that you do, either, with the code you show.

好吧,我运行了那段代码,我得到了“救了它!”这不是人们所期望的吗?我从来没有得到NoM​​ethodError:nil的未定义方法体:NilClass,我也不相信你用你展示的代码。

So what's the problem, really? Is it that the 404 message isn't getting passed out to stdout? If that's what you wanted, you should have written:

那真的是什么问题?难道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


2  

Just a little modification to show the problem:

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

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

No you get a undefined method 'body' for 1:Fixnum

不,你得到一个未定义的方法'body'为1:Fixnum

Explanation: Your method does the puts e.message, but it does not return a result (or in other words: it returns nil.)

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

With file.body you call file (with the result nil). and on this result you call body. But this does not exist for nil. So you get the error undefined method 'body' for nil:NilClass

使用file.body,您可以调用file(结果为nil)。在这个结果你称之为身体。但这不存在为零。所以你得到nil的错误未定义方法'body':NilClass

If I try

如果我试试

f = file
f.body

I get the same error.

我犯了同样的错误。

Are you sure, you use the same url in both calls? If you can open your url, the you retrun a valid object.

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


Actually I can't see your problem without more code.

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

You could check your code for one thing:

你可以检查一下你的代码:

If you define a variable and a method file, then you get the variable. See example below. Perhaps this is the problem.

如果定义变量和方法文件,则获取变量。见下面的例子。也许这就是问题所在。

file = nil
def file
  1
end

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

To be sure to get the method you can try file().

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

#3


0  

This is probably what you want:

这可能是你想要的:

require 'open-uri'

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

Let's try a valid url first:

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

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

And now let's try it with a url that returns a 404:

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

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

Edit: Your code raises two errors when called on non-existing URLs. The 'file' method raises a OpenURI::HTTPError, while the 'body' method will raise a NoMethodError because it's called on nil. In your first usage example, you raise those two errors in one statement. In the second usage example, the errors are sequential. Still, they should yield the same result and they do for me.

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