打破并返回价值的最佳方法

时间:2018-07-05 06:20:58

标签: ruby-on-rails ruby return break

我有一个嵌套在其他两个方法中的方法,并且我希望该方法能够从所有递归方法中break返回错误。例如,如果我在这里叫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

我该如何突破所有父方法并返回因付款失败而导致的卡错误?我需要类似break and return ereturn e and break的东西。但是我知道breakreturn语句都会立即返回,因此我无法将它们链接起来(我不认为)。

我可以在要调用的每个函数中添加return语句,但是我打算在很多地方使用此方法,并且不打算让它表现出不同的行为,因此我正在寻找最可重用的书写方式。

2 个答案:

答案 0 :(得分:5)

为什么您在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

通过引发异常,所有循环都会自动“中断”。

如果您想在pay_order方法内做一些例外处理,那么我建议您再次营救并加薪:

def pay_order
  order.pay
rescue Stripe::CardError => e
  # do your stuff
  raise e
end

答案 1 :(得分:1)

基本上,您可以使用throwraise(分别为fail,请参阅here来讨论使用raise还是fail )。

区别在于,使用raise / fail会产生一个异常(用rescue捕获),并且Exception对象可以包含要返回的数据作为有效载荷。

使用throw,您只需在呼叫链的上方进行 goto 操作即可。着陆点是使用catch定义的(例如,参见here)。它没有任何有效负载,这意味着您需要使用在两侧均可访问的对象(例如,实例变量)将任何数据“传输”回去。