简体   繁体   English

Ruby的throw-catch如何实现?

[英]How is Ruby's throw-catch implemented?

In ruby you can throw :label so long as you've wrapped everything in a catch(:label) do block. 在ruby中,只要将所有内容都包裹在catch(:label) do可以throw :label

I want to add this to a custom lispy language but I'm not sure how it's implemented under the hood. 我想将其添加到自定义的lispy语言中,但是我不确定它是如何实现的。 Any pointers? 有指针吗?

This is an example of a non-local exit. 这是一个非本地出口的示例。 If you are using your host language's (in this case C) call stack for function calls in your target language (so eg a function call in your lisp equates to a function call in C), then the easiest way is to use your host language's form of non-local exit. 如果您使用目标语言的函数调用使用宿主语言的调用栈(在这种情况下为C)(例如,Lisp中的函数调用等同于C的函数调用),那么最简单的方法是使用宿主语言的非本地出口的形式。 In C that means setjmp/longjmp. 在C中,这意味着setjmp / longjmp。

If, however, you are maintaining your target language's call stack separately then you have many options for how to do this. 但是,如果要分别维护目标语言的调用堆栈,则可以选择多种方法。 One really simple way would be to have each lexical-scope exit yield two values; 一种非常简单的方法是让每个词法范围出口产生两个值。 the actual value returned, and an exception state, if any. 返回的实际值和异常状态(如果有)。 Then you can check for the exception at runtime and propagate this value up. 然后,您可以在运行时检查异常并向上传播此值。 This has the downside of incurring extra cost to function calls when no condition is signaled, but may be sufficient for a toy language. 不利的一面是,如果没有发出任何信号,则函数调用会产生额外费用,但对于玩具语言来说可能就足够了。

The book "Lisp In Small Pieces" covers about a half-dozen ways of handling this, if you're interested. 如果您有兴趣的话,《 Lisp In Small Pieces》一书涵盖了大约六种处理方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM