Rewriting JavaScript break-to-label in Ruby
I'm porting a JavaScript library to Ruby, and have come across the following insanity (heavily abbreviated):
function foo(){
if (foo) ...
loop:
while(go()){
if (...) break;
switch(...){
case a:
break loop;
case b:
case c:
if (...)开发者_StackOverflow中文版 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;
}
}
}
(You can view the full horror on lines 701-1006.)
How would you rewrite this in Ruby? Specifically:
- Handling the intermixed
break
andbreak loop
, and - Handling the occasional "fall throughs" that occur in the switch
Presumably a good general strategy for these will get me through other situations, like the nested object_init
breaking that also occurs.
Edit: How silly of me; a JavaScript "fall through" like this:
switch(xxx){
case a:
aaa;
case b:
bbb;
break;
}
can easily be rewritten in Ruby as:
case xxx
when a, b
if a===xxx
aaa
end
bbb
end
There are multiple techniques that will work for this.
I'm sure this has already occurred to you, but for the record, you could extract methods from the nightmare function until its structure looks more reasonable.
You could define the outer loops with lambda and then immediately call them on the next line. This will allow you to use the return statement as a multi-level break and the closure that is created will allow you to still access the outer scope variables.
You could raise an exception and rescue it.
(Added by Phrogz) As suggested in the answer linked by @jleedev, you can use throw/catch, e.g.
catch(:loop) do case ... when a throw :loop when b, c throw :loop if ... ... end end
精彩评论