打破和 return 值的最佳方式
Best way to break and return a value
我有一个嵌套在其他几个方法中的方法,我希望此方法从所有递归方法中 break
并出现 returned 错误。例如,如果我在这里调用 pay_order
:
class API::StripeController < ApiController
def my_api_action
# ...
order = create_order
pay_order(order, token)
# do things if payment is successful
end
end
而pay_order
定义为:
def pay_order(order, token)
begin
order.pay(source: token)
rescue Stripe::CardError => e
break e
end
end
如何突破所有父方法和return支付失败导致的卡错误?我需要 break and return e
或 return e and break
之类的东西。但是我马上就知道 break
和 return
语句 return,所以我不能将它们链接起来(我不认为)。
我可以只向每个被调用的函数添加 return
语句,但我计划在很多地方使用这种方法,并且不打算永远需要它来表现不同,所以我寻找最可重用的编写方式。
你为什么rescue
在pay_order
方法里面?我会在外圈救援。
鉴于以下内容:
def method_a
10.times do |loop_a|
method_b
end
end
def method_b
5.times do |loop_b|
pay_order
end
end
def pay_order
...
end
我会在method_a
里面救援,例如:
def method_a
10.times do |loop_a|
method_b
end
rescue Stripe::CardError => e
# do whatever. no need to break
end
所有循环都是 "broken" 由引发异常自动产生的。
如果你想对pay_order方法中的异常做点什么,那我建议再rescue再raise:
def pay_order
order.pay
rescue Stripe::CardError => e
# do your stuff
raise e
end
基本上可以用throw
,或者raise
(分别是fail
,看讨论是用raise
还是fail
).
不同之处在于,使用 raise/fail,您会产生一个异常(使用 rescue
捕获),并且异常对象可以包含您想要 return.
使用 throw
,您只是在调用链的上游执行某种 goto。着陆点使用 catch
定义(参见 here 示例)。这没有任何有效负载,这意味着您需要 "transport" 使用双方均可访问的对象(例如实例变量)返回任何数据。
我有一个嵌套在其他几个方法中的方法,我希望此方法从所有递归方法中 break
并出现 returned 错误。例如,如果我在这里调用 pay_order
:
class API::StripeController < ApiController
def my_api_action
# ...
order = create_order
pay_order(order, token)
# do things if payment is successful
end
end
而pay_order
定义为:
def pay_order(order, token)
begin
order.pay(source: token)
rescue Stripe::CardError => e
break e
end
end
如何突破所有父方法和return支付失败导致的卡错误?我需要 break and return e
或 return e and break
之类的东西。但是我马上就知道 break
和 return
语句 return,所以我不能将它们链接起来(我不认为)。
我可以只向每个被调用的函数添加 return
语句,但我计划在很多地方使用这种方法,并且不打算永远需要它来表现不同,所以我寻找最可重用的编写方式。
你为什么rescue
在pay_order
方法里面?我会在外圈救援。
鉴于以下内容:
def method_a
10.times do |loop_a|
method_b
end
end
def method_b
5.times do |loop_b|
pay_order
end
end
def pay_order
...
end
我会在method_a
里面救援,例如:
def method_a
10.times do |loop_a|
method_b
end
rescue Stripe::CardError => e
# do whatever. no need to break
end
所有循环都是 "broken" 由引发异常自动产生的。
如果你想对pay_order方法中的异常做点什么,那我建议再rescue再raise:
def pay_order
order.pay
rescue Stripe::CardError => e
# do your stuff
raise e
end
基本上可以用throw
,或者raise
(分别是fail
,看raise
还是fail
).
不同之处在于,使用 raise/fail,您会产生一个异常(使用 rescue
捕获),并且异常对象可以包含您想要 return.
使用 throw
,您只是在调用链的上游执行某种 goto。着陆点使用 catch
定义(参见 here 示例)。这没有任何有效负载,这意味着您需要 "transport" 使用双方均可访问的对象(例如实例变量)返回任何数据。