Ruby 为什么可以';t我捕捉到了“中的测试异常”;呼叫者;方法

Ruby 为什么可以';t我捕捉到了“中的测试异常”;呼叫者;方法,ruby,exception,Ruby,Exception,我不明白为什么这个代码不能正常工作: def test raise Exception.new 'error' end def caller begin test rescue =>e puts e.message end end caller 我想在调用者方法中捕获测试异常,但是调用者方法似乎没有捕获任何东西。您应该指定希望救援的异常类型。试一试 rescue Exception => e 简比我快,但是 将=>var语法与异常一起使用

我不明白为什么这个代码不能正常工作:

def test
  raise Exception.new 'error'
end

def caller
  begin
    test
  rescue =>e
     puts e.message
  end
end

caller

我想在
调用者
方法中捕获测试异常,但是
调用者
方法似乎没有捕获任何东西。

您应该指定希望
救援的异常类型。试一试

  rescue Exception => e

简比我快,但是

=>var
语法与
异常
一起使用时,必须指定要挽救的异常类型。所有异常的基类都是Exception,因此如果您将其更改为
rescue Exception=>e
,它将起作用。此外,当您要拯救的是方法的整个主体时,您不需要显式的开始…结束块

def test
  raise Exception.new 'error'
end

def caller
  test
rescue Exception =>e
  puts e.message
end

caller()

代码不工作的原因是没有明确说明异常类型的
rescue
只捕获
standarderor
,它是
异常的子类。由于您正在引发高于
标准错误的
异常
,因此您的
救援
无法捕获它


通常,您希望使用更具体的异常,并且几乎不需要在
标准错误
上使用
异常

例如,这可以很好地工作:

begin
  raise StandardError.new 'Uh-oh!'
rescue => e
  p e.message
end

#=> Uh-oh!

谢谢,这很有效。我无法理解投掷和提升陈述之间的区别…不一定…请看我的答案。通常,营救异常=>e
不是一个好主意,因为您捕获的异常级别可能低于应用程序准备处理的级别。@BenD,抛出/抛出差异。我同意coreyward的观点:最好的建议是首先不要提出
异常
,但使用更具体的错误类,如
StandardError
,同样,这不一定正确。您可能不想
rescue Exception=>e
,因为您将捕获比您的程序能够处理的级别更低的异常。当然,我应该提到的是,拯救
Exception
通常不是一件好事。在这种情况下,
异常
是引发的,但是,…fwiw,在方法中执行
开始救援结束
时,可以删除
开始
结束
。保存几行代码,即
def调用者;测验救援例外=>e;把电子讯息;结束
作为一种风格,在引发异常时不需要使用
new
<代码>引发异常,“错误”
就足够了。“通常,您希望使用更具体的异常”,同意。增加的粒度有助于处理“作战条件”中的流控制。