在Ruby中重写JavaScript break-to-label
我正在将一个JavaScript库移植到Ruby,并且遇到了以下精神错乱(严重缩写):
function foo(){ if (foo) ... loop: while(go()){ if (...) break; switch(...){ case a: break loop; case b: case c: if (...) break loop; ... break; case d: if (...) break loop; // fall through case e: if (...) break loop; ... break; case f: if (...) break loop; object_init: do{ switch(...){ case a: ... break; case b: ... break object_init; } } while(...); ... break; } } }
(你可以在第701-1006行看到完整的恐怖。)
你会如何在Ruby中重写它? 特别:
- 处理混合的
break
和break loop
,和 - 处理交换机中偶然发生的“跌落”
据推测,这些的一般策略很好会让我通过其他情况,比如嵌套的object_init
破坏也会发生。
编辑 :我有多傻; 像这样的JavaScript“堕落”:
switch(xxx){ case a: aaa; case b: bbb; break; }
可以很容易地在Ruby中重写为:
case xxx when a, b if a===xxx aaa end bbb end
有多种技术可以解决这个问题。
-
我确信这已经发生在你身上,但是为了记录,你可以从噩梦函数中提取方法,直到它的结构看起来更合理。
-
您可以使用lambda定义外部循环,然后立即在下一行调用它们。 这将允许您将return语句用作多级中断 ,并且创建的闭包将允许您仍然访问外部作用域变量。
-
你可以提出exception并拯救它。
-
(由Phrogz添加)正如@jleedev链接的答案所示,你可以使用throw / catch,例如
catch(:loop) do case ... when a throw :loop when b, c throw :loop if ... ... end end