15

So, I've tried break, next and return. They all give errors, exit of course works, but that completely exits. So, how would one end a case...when "too soon?"

Example:

case x
    when y; begin
        <code here>
        < ** terminate somehow ** > if something
        <more code>
    end
end

(The above is some form of pseudo-code just to give the general idea of what I'm asking [begin...end was used with the hope that break would work].

And, while I'm at it, is there a more elegant way of passing blocks to case...when?

omninonsense
  • 6,644
  • 9
  • 45
  • 66

3 Answers3

7

What's wrong with:

case x
when y;
    <code here>
    if !something
        <more code>
    end
end

Note that if !something is the same as unless something

Gareth
  • 133,157
  • 36
  • 148
  • 157
  • Absolutely nothing! It did cross my mind, but I was looking for the _right_ way of doing it. I assumed there was a right way, apart from this one. So, if there's no other way of doing it, I guess _this_ is the right way. Thanks! :D – omninonsense Nov 05 '11 at 20:14
  • 1
    Wrong is indentation. If it wasn't wrong, then the language won't need at all neither `break` nor `next`. – Nakilon Feb 18 '13 at 19:06
5

Ruby has no built-in way to exit the "when" in a "case" statement. You could however get the desired outcome with an answer similar to the technique WarHog gave:

case x
when y
    begin
        <code here>
        break if something
        <more code>
    end while false
end

or if you prefer:

case x
when y
    1.times do
        <code here>
        break if something
        <more code>
    end
end
NoonKnight
  • 153
  • 5
  • 8
  • That would exit the inner loop. Not the case-when. Try adding a `puts "this should not be written"` after the loop and make the break condition true – user9869932 Mar 12 '21 at 23:53
  • user9869932 - good point , you are correct since Ruby has no built-in way to exit the "when" in a "case" statement. this answer is a suggested way to get the desired outcome. guess it assumes that code you want to skip is within the loop. – NoonKnight Mar 18 '21 at 17:23
5

I see a couple of possible solutions. At the first hand, you can define your block of instructions inside some method:

def test_method
  <code here>
  return if something
  <more code>
end

case x
  when y
    test_method
end

At the other hand, you can use catch-throw, but I believe it's more uglier and non-ruby way :)

catch :exit do
  case x
    when y
      begin
        <code here>
        throw :exit if something
        <more code>
      end
  end
end
WarHog
  • 8,622
  • 2
  • 29
  • 23
  • Well, if I created a method for every case it would look weird, really weird (and there's a lot of cases) and the second example _does_ look a bit... Eh. +1 for creativity, though. – omninonsense Nov 05 '11 at 20:16
  • but wait, that return only returns from the method and doesn't break the case statement, right? – Michael K Madison Jun 26 '13 at 17:27