ruby中的异常处理机制分析

ruby是一门动态脚本语言,这个大家都知道。

我今天想讨论的问题是ruby中的异常处理机制,首先贴一段代码:

 1 class SocketError < StandardError  
 2 end
 3 
 4 class Test
 5   @host = "192.168.0.1"
 6   @port = 8000
 7   def opensocket
 8     ret_str = "socket open Fail"
 9     begin
10       socket = TCPSocket.open(@host,@port)
11       ret_str = "socket open successed!"
12     rescue => e
13       puts "socket error"
14       raise SocketError 
15     end 
16     return ret_str
17   end
18 end
19 
20 #############################
21 = Test.new
22 begin
23   str = t.opensocket()
24   puts str
25 rescue SocketError
26   puts "socket open fail  in opensocket method"
27 end
28 #############################

这段代码打印的结果大家都应该会知道:

socket error
socket open fail  in opensocket method
在看下下面的这段代码

 

 1 class SocketError < StandardError  
 2 end
 3 
 4 class Test
 5   @host = "192.168.0.1"
 6   @port = 8000
 7   def opensocket
 8     ret_str = "socket open Fail"
 9     begin
10       socket = TCPSocket.open(@host,@port)
11       ret_str = "socket open successed!"
12     rescue => e
13       puts "socket error"
14       raise SocketError 
15     ensure
16       return ret_str
17     end 
18   end
19 end
20 
21 #############################
22 = Test.new
23 begin
24   str = t.opensocket()
25   puts str
26 rescue SocketError
27   puts "socket open fail  in opensocket method"
28 end
29 #############################
30 
31 

大家说这段代码返回的是什么?

还是和上面的代码返回的结果一致么?

结果是:

socket error
socket open Fail
大家可能想“为什么他能返回的结果是:socket open Fail ,在在外层的resure中为什么不能接收到异常呢?为什么不能打印 socket open fail  in opensocket method“

 

今天要讨论的问题就是这个。

在第二段代码与第一段代码的不同就是:return 语句放置 的位置不同。在第二段代码中吧return 放在 ensure中 ,第一段代码则是放置在 begin ... end语言之后。

其实就是这点的原因导致了上面的结果。在代码段2中,我们只是在是希望在异常的善后处理中能把我们想要的值返回去。

这样做将导致一个结果就是,在之前的rescue中raise 的异常将因为这个return而被”吃“掉。  也就是说,这个时候的他就不把raise 这个异常往上抛了,自己处理了,

其实在强类型语言里是不允许在ensure中return的。

例如在C#语言中,在try...catch...finally 的 finally中是不允许有return的,这样就避免了这样的问题发生。


posted @ 2010-05-17 14:18  星球人  阅读(938)  评论(0编辑  收藏  举报