nTraum
nTraum

Reputation: 1426

Equivalent for `break` in ruby's case / when statements?

I'm looking for a statement that skips the execution of the when block, similiar to break for loops. Is this possible?

What I want to avoid is a construct like:

case n
  when 1
    if valid
      foo.bar
    end
  when 2
    if valid
      foo.foo
  end

The more desirable code block would look like:

case n
  when 1
    break unless valid
    foo.bar
  when 2
    break unless valid
    foo.foo
  end

Obviously, break does not work.

Upvotes: 4

Views: 1501

Answers (4)

Garth Good
Garth Good

Reputation: 1

You can accomplish this functionality using closures. Closures are possible in ruby using the lambda syntax (-> can be replaced with the lambda keyword). This is because lambdas act as their own standalone function and return will exit the lambda/function without exiting the parent block/scope:

def valid(q)
  q == 2
end

def test_break(myvar)
  -> (n) {
    case n
      when 1
        return unless valid(n)
        puts 'I am not valid'
      when 2
        return unless valid(n)
        puts 'I am valid'
      end
  }.(myvar)

  puts 'I am run every time'
end

test_break(1)
test_break(2)

# Output:
# I am run every time
# I am valid
# I am run every time

Lambda syntax:

def valid(q)
  q == 2
end

def test_break(myvar)
  lambda do |n|
    case n
        when 1
          return unless valid(n)
          puts 'I am not valid'
        when 2
          return unless valid(n)
          puts 'I am valid'
        end
  end.call(myvar)

  puts 'I am run every time'
end

test_break(1)
test_break(2)

# Output:
# I am run every time
# I am valid
# I am run every time

More info on closures here:

What is the difference between a 'closure' and a 'lambda'?

Upvotes: 0

Sascha
Sascha

Reputation: 159

What I did in one case, which might be applicable to your case is encapsulating in a loop;

loop do
  case variable
  when conditionalA
    block1
    next if anotherconditional
    blockX
  when conditionalB
    block2
    next if anotherconditional
    blockY
  end
end

Though not sure if this is "fine art".

Upvotes: 0

Thilo
Thilo

Reputation: 17735

Equivalent but more succinct:

case n
  when 1
    foo.bar if valid
  when 2
    foo.foo if valid
  end
end

of if the condition really applies to all cases, you can check it beforehand:

if valid
  case n
    when 1
      foo.bar
    when 2
      foo.foo
    end
  end
end

If neither works for you, then short answer: No, there's no break equivalent in a case statement in ruby.

Upvotes: 7

jebentier
jebentier

Reputation: 151

I'm always a fan of adding conditionals to the end of ruby statements. It makes for easier and more readable code. Which is what ruby is known for. My answer to your question would look something like this:

case n
when 1
    foo.bar
when 2
    bar.foo
end unless !valid

Upvotes: 2

Related Questions