【问题标题】:Where are catch and throw useful in Ruby?在 Ruby 中,catch 和 throw 有什么用处?
【发布时间】:2010-01-07 04:03:04
【问题描述】:

我真的不认为这些有合理的用途。已经有rescueraise,那为什么还需要throwcatch?似乎它们应该被用来跳出深巢,但这对我来说就像一个goto。有没有什么好的、干净的使用这些的例子?

【问题讨论】:

    标签: ruby


    【解决方案1】:

    注意: 1.9 中的 catch/throw 似乎发生了一些变化。这个答案适用于 Ruby 1.9。

    一个很大的不同是你可以throw 任何东西,而不仅仅是从StandardError 派生的东西,不像raise。像这样的傻事是合法的,例如:

    throw Customer.new
    

    但这并不是很有意义。但你不能这样做:

    irb(main):003:0> raise Customer.new
    TypeError: exception class/object expected
        from (irb):3:in `raise'
        from (irb):3
        from /usr/local/bin/irb:12:in `<main>'
    

    【讨论】:

    • 这个例子对于救援/提升也是合法的。它只是说“救援条款所需的类或模块”。
    • 另外,它告诉我你只能捕捉/扔一个符号。
    • @jleedev » 你运行的是哪个版本的 Ruby? [编辑:哎呀,我误读了你所说的。最后一句话我打错了,会改正的。]
    • 在 ruby​​ 1.8.6 中。投掷/举起错误类型的东西:codepad.org/oFYEardW
    • @jleedev:在 1.9 中这是可行的,所以这就解释了。有趣!
    【解决方案2】:

    它们在为最终用户简化 DSL 方面非常有用,可以将控制权从 DSL 中传递出去,而无需复杂的 case/if 语句

    我有一个 Ruby 应用程序,它允许用户通过内部 DSL 对其进行扩展。 DSL 中的某些功能需要将控制权返回给我的应用程序的特定部分。让我们举一个简单的例子。假设用户正在开发一个关于日期的简单扩展

    if today is a holiday then
       do nothing
    end
    
    week_of_year = today.week.number
    
    if week_of_year < 10 then
    
    ...
    

    do nothing 位触发了一个 throw,它将控制权从 exec 语句中传递给我。

    在某些情况下,我们希望它退出并将控制权交还给我的应用程序,而不是继续执行 DSL。现在您可以让用户使用大量嵌入的 if 语句并让 DSL 自然结束,但这只会掩盖逻辑想要表达的意思。

    Throw 确实是一个“被认为很危险”的 goto,但该死的,有时它们是最好的解决方案。

    【讨论】:

      【解决方案3】:

      它基本上是一个 goto,有点类似于 call/cc,除了控制流是通过名称隐式连接的,而不是作为参数显式连接。 throw/catch 和 raise/rescue 的区别在于前者旨在用于控制流而不是仅用于异常情况,并且不会浪费时间整理堆栈跟踪。

      Sinatra 使用 throw/catch 处理 HTTP 错误代码,其中处理程序可以使用 throw 以结构化的方式将控制权交给 Sinatra 库。其他类型的 HTTP 框架使用异常,或者通过返回不同类的响应,但这让 Sinatra(例如)在捕获它之后尝试另一个请求处理程序。

      【讨论】:

        【解决方案4】:

        两者的区别在于你只能“引发”异常,但可以“抛出”任何东西(1.9)。除此之外,它们应该是可互换的,也就是说,应该可以相互重写,就像@john-feminella 给出的例子一样。

        【讨论】:

          猜你喜欢
          • 2011-04-12
          • 1970-01-01
          • 1970-01-01
          • 2013-11-24
          • 2012-06-04
          • 1970-01-01
          • 1970-01-01
          • 2014-03-18
          • 2013-01-18
          相关资源
          最近更新 更多